Completed
Push — ezp-30147 ( 4b6c34...8feb09 )
by
unknown
21:46
created

LocationServiceTest::testUpdateLocationTwice()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 23
rs 9.552
c 0
b 0
f 0
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 Exception;
12
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
13
use eZ\Publish\API\Repository\Values\Content\Content;
14
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
15
use eZ\Publish\API\Repository\Values\Content\Location;
16
use eZ\Publish\API\Repository\Values\Content\LocationCreateStruct;
17
use eZ\Publish\API\Repository\Values\Content\LocationList;
18
use eZ\Publish\API\Repository\Values\Content\Query;
19
use eZ\Publish\API\Repository\Values\Content\Search\SearchHit;
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
    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
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
263
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
264
     */
265
    public function testCreateLocationInTransactionWithRollback()
266
    {
267
        $repository = $this->getRepository();
268
269
        $contentId = $this->generateId('object', 41);
270
        $parentLocationId = $this->generateId('location', 5);
271
        /* BEGIN: Use Case */
272
        // $contentId is the ID of an existing content object
273
        // $parentLocationId is the ID of an existing location
274
        $contentService = $repository->getContentService();
275
        $locationService = $repository->getLocationService();
276
277
        $repository->beginTransaction();
278
279
        try {
280
            // ContentInfo for "How to use eZ Publish"
281
            $contentInfo = $contentService->loadContentInfo($contentId);
282
283
            $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
284
            $locationCreate->remoteId = 'sindelfingen';
285
286
            $createdLocationId = $locationService->createLocation(
287
                $contentInfo,
288
                $locationCreate
289
            )->id;
290
        } catch (Exception $e) {
291
            // Cleanup hanging transaction on error
292
            $repository->rollback();
293
            throw $e;
294
        }
295
296
        $repository->rollback();
297
298
        try {
299
            // Throws exception since creation of location was rolled back
300
            $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...
301
        } catch (NotFoundException $e) {
302
            return;
303
        }
304
        /* END: Use Case */
305
306
        $this->fail('Objects still exists after rollback.');
307
    }
308
309
    /**
310
     * Test for the loadLocation() method.
311
     *
312
     * @return \eZ\Publish\API\Repository\Values\Content\Location
313
     *
314
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
315
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
316
     */
317 View Code Duplication
    public function testLoadLocation()
318
    {
319
        $repository = $this->getRepository();
320
321
        $locationId = $this->generateId('location', 5);
322
        /* BEGIN: Use Case */
323
        // $locationId is the ID of an existing location
324
        $locationService = $repository->getLocationService();
325
326
        $location = $locationService->loadLocation($locationId);
327
        /* END: Use Case */
328
329
        $this->assertInstanceOf(
330
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
331
            $location
332
        );
333
334
        return $location;
335
    }
336
337
    /**
338
     * Test for the loadLocation() method.
339
     *
340
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
341
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
342
     */
343
    public function testLoadLocationRootStructValues()
344
    {
345
        $repository = $this->getRepository();
346
        $locationService = $repository->getLocationService();
347
        $location = $locationService->loadLocation($this->generateId('location', 1));
348
349
        $legacyDateTime = new \DateTime();
350
        $legacyDateTime->setTimestamp(1030968000);
351
352
        // $location
353
        $this->assertPropertiesCorrect(
354
            array(
355
                'id' => $this->generateId('location', 1),
356
                'status' => 1,
357
                'priority' => 0,
358
                'hidden' => false,
359
                'invisible' => false,
360
                'remoteId' => '629709ba256fe317c3ddcee35453a96a',
361
                'parentLocationId' => $this->generateId('location', 1),
362
                'pathString' => '/1/',
363
                'depth' => 0,
364
                'sortField' => 1,
365
                'sortOrder' => 1,
366
            ),
367
            $location
368
        );
369
370
        // $location->contentInfo
371
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $location->contentInfo);
372
        $this->assertPropertiesCorrect(
373
            array(
374
                'id' => $this->generateId('content', 0),
375
                'name' => 'Top Level Nodes',
376
                'sectionId' => 1,
377
                'mainLocationId' => 1,
378
                'contentTypeId' => 1,
379
                'currentVersionNo' => 1,
380
                'published' => 1,
381
                'ownerId' => 14,
382
                'modificationDate' => $legacyDateTime,
383
                'publishedDate' => $legacyDateTime,
384
                'alwaysAvailable' => 1,
385
                'remoteId' => null,
386
                'mainLanguageCode' => 'eng-GB',
387
            ),
388
            $location->contentInfo
389
        );
390
    }
391
392
    /**
393
     * Test for the loadLocation() method.
394
     *
395
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
396
     *
397
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
398
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
399
     */
400
    public function testLoadLocationStructValues(Location $location)
401
    {
402
        $this->assertPropertiesCorrect(
403
            array(
404
                'id' => $this->generateId('location', 5),
405
                'priority' => 0,
406
                'hidden' => false,
407
                'invisible' => false,
408
                'remoteId' => '3f6d92f8044aed134f32153517850f5a',
409
                'parentLocationId' => $this->generateId('location', 1),
410
                'pathString' => '/1/5/',
411
                'depth' => 1,
412
                'sortField' => 1,
413
                'sortOrder' => 1,
414
            ),
415
            $location
416
        );
417
418
        $this->assertInstanceOf(
419
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo',
420
            $location->contentInfo
421
        );
422
        $this->assertEquals($this->generateId('object', 4), $location->contentInfo->id);
423
    }
424
425
    /**
426
     * Test for the loadLocation() method.
427
     *
428
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
429
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
430
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
431
     */
432
    public function testLoadLocationThrowsNotFoundException()
433
    {
434
        $repository = $this->getRepository();
435
436
        $nonExistentLocationId = $this->generateId('location', 2342);
437
        /* BEGIN: Use Case */
438
        $locationService = $repository->getLocationService();
439
440
        // Throws exception, if Location with $nonExistentLocationId does not
441
        // exist
442
        $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...
443
        /* END: Use Case */
444
    }
445
446
    /**
447
     * Test for the loadLocationByRemoteId() method.
448
     *
449
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationByRemoteId()
450
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
451
     */
452 View Code Duplication
    public function testLoadLocationByRemoteId()
453
    {
454
        $repository = $this->getRepository();
455
456
        /* BEGIN: Use Case */
457
        $locationService = $repository->getLocationService();
458
459
        $location = $locationService->loadLocationByRemoteId(
460
            '3f6d92f8044aed134f32153517850f5a'
461
        );
462
        /* END: Use Case */
463
464
        $this->assertEquals(
465
            $locationService->loadLocation($this->generateId('location', 5)),
466
            $location
467
        );
468
    }
469
470
    /**
471
     * Test for the loadLocationByRemoteId() method.
472
     *
473
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationByRemoteId()
474
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
475
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
476
     */
477
    public function testLoadLocationByRemoteIdThrowsNotFoundException()
478
    {
479
        $repository = $this->getRepository();
480
481
        /* BEGIN: Use Case */
482
        $locationService = $repository->getLocationService();
483
484
        // Throws exception, since Location with remote ID does not exist
485
        $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...
486
            'not-exists'
487
        );
488
        /* END: Use Case */
489
    }
490
491
    /**
492
     * Test for the loadLocations() method.
493
     *
494
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
495
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
496
     */
497
    public function testLoadLocations()
498
    {
499
        $repository = $this->getRepository();
500
501
        $contentId = $this->generateId('object', 4);
502
        /* BEGIN: Use Case */
503
        // $contentId contains the ID of an existing content object
504
        $contentService = $repository->getContentService();
505
        $locationService = $repository->getLocationService();
506
507
        $contentInfo = $contentService->loadContentInfo($contentId);
508
509
        $locations = $locationService->loadLocations($contentInfo);
510
        /* END: Use Case */
511
512
        $this->assertInternalType('array', $locations);
513
514
        return $locations;
515
    }
516
517
    /**
518
     * Test for the loadLocations() method.
519
     *
520
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
521
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
522
     */
523
    public function testLoadLocationsContent(array $locations)
524
    {
525
        $repository = $this->getRepository();
526
        $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...
527
528
        $this->assertEquals(1, count($locations));
529
        foreach ($locations as $loadedLocation) {
530
            $this->assertInstanceOf(
531
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
532
                $loadedLocation
533
            );
534
        }
535
536
        usort(
537
            $locations,
538
            function ($a, $b) {
539
                strcmp($a->id, $b->id);
540
            }
541
        );
542
543
        $this->assertEquals(
544
            array($this->generateId('location', 5)),
545
            array_map(
546
                function (Location $location) {
547
                    return $location->id;
548
                },
549
                $locations
550
            )
551
        );
552
    }
553
554
    /**
555
     * Test for the loadLocations() method.
556
     *
557
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
558
     *
559
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations($contentInfo, $rootLocation)
560
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
561
     */
562
    public function testLoadLocationsLimitedSubtree()
563
    {
564
        $repository = $this->getRepository();
565
566
        $originalLocationId = $this->generateId('location', 54);
567
        $originalParentLocationId = $this->generateId('location', 48);
568
        $newParentLocationId = $this->generateId('location', 43);
569
        /* BEGIN: Use Case */
570
        // $originalLocationId is the ID of an existing location
571
        // $originalParentLocationId is the ID of the parent location of
572
        //     $originalLocationId
573
        // $newParentLocationId is the ID of an existing location outside the tree
574
        // of $originalLocationId and $originalParentLocationId
575
        $locationService = $repository->getLocationService();
576
577
        // Location at "/1/48/54"
578
        $originalLocation = $locationService->loadLocation($originalLocationId);
579
580
        // Create location under "/1/43/"
581
        $locationCreate = $locationService->newLocationCreateStruct($newParentLocationId);
582
        $locationService->createLocation(
583
            $originalLocation->contentInfo,
584
            $locationCreate
585
        );
586
587
        $findRootLocation = $locationService->loadLocation($originalParentLocationId);
588
589
        // Returns an array with only $originalLocation
590
        $locations = $locationService->loadLocations(
591
            $originalLocation->contentInfo,
592
            $findRootLocation
593
        );
594
        /* END: Use Case */
595
596
        $this->assertInternalType('array', $locations);
597
598
        return $locations;
599
    }
600
601
    /**
602
     * Test for the loadLocations() method.
603
     *
604
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
605
     *
606
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
607
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationsLimitedSubtree
608
     */
609
    public function testLoadLocationsLimitedSubtreeContent(array $locations)
610
    {
611
        $this->assertEquals(1, count($locations));
612
613
        $this->assertEquals(
614
            $this->generateId('location', 54),
615
            reset($locations)->id
616
        );
617
    }
618
619
    /**
620
     * Test for the loadLocations() method.
621
     *
622
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
623
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
624
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
625
     */
626 View Code Duplication
    public function testLoadLocationsThrowsBadStateException()
627
    {
628
        $repository = $this->getRepository();
629
630
        /* BEGIN: Use Case */
631
        $contentTypeService = $repository->getContentTypeService();
632
        $contentService = $repository->getContentService();
633
        $locationService = $repository->getLocationService();
634
635
        // Create new content, which is not published
636
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
637
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
638
        $contentCreate->setField('name', 'New Folder');
639
        $content = $contentService->createContent($contentCreate);
640
641
        // Throws Exception, since $content has no published version, yet
642
        $locationService->loadLocations(
643
            $content->contentInfo
644
        );
645
        /* END: Use Case */
646
    }
647
648
    /**
649
     * Test for the loadLocations() method.
650
     *
651
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations($contentInfo, $rootLocation)
652
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
653
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
654
     */
655
    public function testLoadLocationsThrowsBadStateExceptionLimitedSubtree()
656
    {
657
        $repository = $this->getRepository();
658
659
        $someLocationId = $this->generateId('location', 2);
660
        /* BEGIN: Use Case */
661
        // $someLocationId is the ID of an existing location
662
        $contentTypeService = $repository->getContentTypeService();
663
        $contentService = $repository->getContentService();
664
        $locationService = $repository->getLocationService();
665
666
        // Create new content, which is not published
667
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
668
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
669
        $contentCreate->setField('name', 'New Folder');
670
        $content = $contentService->createContent($contentCreate);
671
672
        $findRootLocation = $locationService->loadLocation($someLocationId);
673
674
        // Throws Exception, since $content has no published version, yet
675
        $locationService->loadLocations(
676
            $content->contentInfo,
677
            $findRootLocation
678
        );
679
        /* END: Use Case */
680
    }
681
682
    /**
683
     * Test for the loadLocationChildren() method.
684
     *
685
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren()
686
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
687
     */
688 View Code Duplication
    public function testLoadLocationChildren()
689
    {
690
        $repository = $this->getRepository();
691
692
        $locationId = $this->generateId('location', 5);
693
        /* BEGIN: Use Case */
694
        // $locationId is the ID of an existing location
695
        $locationService = $repository->getLocationService();
696
697
        $location = $locationService->loadLocation($locationId);
698
699
        $childLocations = $locationService->loadLocationChildren($location);
700
        /* END: Use Case */
701
702
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
703
        $this->assertInternalType('array', $childLocations->locations);
704
        $this->assertInternalType('int', $childLocations->totalCount);
705
706
        return $childLocations;
707
    }
708
709
    /**
710
     * Test for the getLocationChildCount() method.
711
     *
712
     * @see \eZ\Publish\API\Repository\LocationService::getLocationChildCount()
713
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
714
     */
715
    public function testGetLocationChildCount()
716
    {
717
        // $locationId is the ID of an existing location
718
        $locationService = $this->getRepository()->getLocationService();
719
720
        $this->assertSame(
721
            5,
722
            $locationService->getLocationChildCount(
723
                $locationService->loadLocation($this->generateId('location', 5))
724
            )
725
        );
726
    }
727
728
    /**
729
     * Test for the loadLocationChildren() method.
730
     *
731
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren()
732
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
733
     */
734
    public function testLoadLocationChildrenData(LocationList $locations)
735
    {
736
        $this->assertEquals(5, count($locations->locations));
737
        $this->assertEquals(5, $locations->totalCount);
738
739
        foreach ($locations->locations as $location) {
740
            $this->assertInstanceOf(
741
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
742
                $location
743
            );
744
        }
745
746
        $this->assertEquals(
747
            array(
748
                $this->generateId('location', 12),
749
                $this->generateId('location', 13),
750
                $this->generateId('location', 14),
751
                $this->generateId('location', 44),
752
                $this->generateId('location', 61),
753
            ),
754
            array_map(
755
                function (Location $location) {
756
                    return $location->id;
757
                },
758
                $locations->locations
759
            )
760
        );
761
    }
762
763
    /**
764
     * Test for the loadLocationChildren() method.
765
     *
766
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
767
     *
768
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset)
769
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
770
     */
771 View Code Duplication
    public function testLoadLocationChildrenWithOffset()
772
    {
773
        $repository = $this->getRepository();
774
775
        $locationId = $this->generateId('location', 5);
776
        /* BEGIN: Use Case */
777
        // $locationId is the ID of an existing location
778
        $locationService = $repository->getLocationService();
779
780
        $location = $locationService->loadLocation($locationId);
781
782
        $childLocations = $locationService->loadLocationChildren($location, 2);
783
        /* END: Use Case */
784
785
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
786
        $this->assertInternalType('array', $childLocations->locations);
787
        $this->assertInternalType('int', $childLocations->totalCount);
788
789
        return $childLocations;
790
    }
791
792
    /**
793
     * Test for the loadLocationChildren() method.
794
     *
795
     * @param \eZ\Publish\API\Repository\Values\Content\LocationList $locations
796
     *
797
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset)
798
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildrenWithOffset
799
     */
800 View Code Duplication
    public function testLoadLocationChildrenDataWithOffset(LocationList $locations)
801
    {
802
        $this->assertEquals(3, count($locations->locations));
803
        $this->assertEquals(5, $locations->totalCount);
804
805
        foreach ($locations->locations as $location) {
806
            $this->assertInstanceOf(
807
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
808
                $location
809
            );
810
        }
811
812
        $this->assertEquals(
813
            array(
814
                $this->generateId('location', 14),
815
                $this->generateId('location', 44),
816
                $this->generateId('location', 61),
817
            ),
818
            array_map(
819
                function (Location $location) {
820
                    return $location->id;
821
                },
822
                $locations->locations
823
            )
824
        );
825
    }
826
827
    /**
828
     * Test for the loadLocationChildren() method.
829
     *
830
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
831
     *
832
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset, $limit)
833
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
834
     */
835 View Code Duplication
    public function testLoadLocationChildrenWithOffsetAndLimit()
836
    {
837
        $repository = $this->getRepository();
838
839
        $locationId = $this->generateId('location', 5);
840
        /* BEGIN: Use Case */
841
        // $locationId is the ID of an existing location
842
        $locationService = $repository->getLocationService();
843
844
        $location = $locationService->loadLocation($locationId);
845
846
        $childLocations = $locationService->loadLocationChildren($location, 2, 2);
847
        /* END: Use Case */
848
849
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
850
        $this->assertInternalType('array', $childLocations->locations);
851
        $this->assertInternalType('int', $childLocations->totalCount);
852
853
        return $childLocations;
854
    }
855
856
    /**
857
     * Test for the loadLocationChildren() method.
858
     *
859
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
860
     *
861
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset, $limit)
862
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildrenWithOffsetAndLimit
863
     */
864 View Code Duplication
    public function testLoadLocationChildrenDataWithOffsetAndLimit(LocationList $locations)
865
    {
866
        $this->assertEquals(2, count($locations->locations));
867
        $this->assertEquals(5, $locations->totalCount);
868
869
        foreach ($locations->locations as $location) {
870
            $this->assertInstanceOf(
871
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
872
                $location
873
            );
874
        }
875
876
        $this->assertEquals(
877
            array(
878
                $this->generateId('location', 14),
879
                $this->generateId('location', 44),
880
            ),
881
            array_map(
882
                function (Location $location) {
883
                    return $location->id;
884
                },
885
                $locations->locations
886
            )
887
        );
888
    }
889
890
    /**
891
     * Test for the newLocationUpdateStruct() method.
892
     *
893
     * @see \eZ\Publish\API\Repository\LocationService::newLocationUpdateStruct()
894
     */
895
    public function testNewLocationUpdateStruct()
896
    {
897
        $repository = $this->getRepository();
898
899
        /* BEGIN: Use Case */
900
        $locationService = $repository->getLocationService();
901
902
        $updateStruct = $locationService->newLocationUpdateStruct();
903
        /* END: Use Case */
904
905
        $this->assertInstanceOf(
906
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationUpdateStruct',
907
            $updateStruct
908
        );
909
    }
910
911
    /**
912
     * Test for the updateLocation() method.
913
     *
914
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
915
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
916
     */
917
    public function testUpdateLocation()
918
    {
919
        $repository = $this->getRepository();
920
921
        $originalLocationId = $this->generateId('location', 5);
922
        /* BEGIN: Use Case */
923
        // $originalLocationId is the ID of an existing location
924
        $locationService = $repository->getLocationService();
925
926
        $originalLocation = $locationService->loadLocation($originalLocationId);
927
928
        $updateStruct = $locationService->newLocationUpdateStruct();
929
        $updateStruct->priority = 3;
930
        $updateStruct->remoteId = 'c7adcbf1e96bc29bca28c2d809d0c7ef69272651';
931
        $updateStruct->sortField = Location::SORT_FIELD_PRIORITY;
932
        $updateStruct->sortOrder = Location::SORT_ORDER_DESC;
933
934
        $updatedLocation = $locationService->updateLocation($originalLocation, $updateStruct);
935
        /* END: Use Case */
936
937
        $this->assertInstanceOf(
938
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
939
            $updatedLocation
940
        );
941
942
        return array(
943
            'originalLocation' => $originalLocation,
944
            'updateStruct' => $updateStruct,
945
            'updatedLocation' => $updatedLocation,
946
        );
947
    }
948
949
    /**
950
     * Test for the updateLocation() method.
951
     *
952
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
953
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testUpdateLocation
954
     */
955
    public function testUpdateLocationStructValues(array $data)
956
    {
957
        $originalLocation = $data['originalLocation'];
958
        $updateStruct = $data['updateStruct'];
959
        $updatedLocation = $data['updatedLocation'];
960
961
        $this->assertPropertiesCorrect(
962
            array(
963
                'id' => $originalLocation->id,
964
                'priority' => $updateStruct->priority,
965
                'hidden' => $originalLocation->hidden,
966
                'invisible' => $originalLocation->invisible,
967
                'remoteId' => $updateStruct->remoteId,
968
                'contentInfo' => $originalLocation->contentInfo,
969
                'parentLocationId' => $originalLocation->parentLocationId,
970
                'pathString' => $originalLocation->pathString,
971
                'depth' => $originalLocation->depth,
972
                'sortField' => $updateStruct->sortField,
973
                'sortOrder' => $updateStruct->sortOrder,
974
            ),
975
            $updatedLocation
976
        );
977
    }
978
979
    /**
980
     * Test for the updateLocation() method.
981
     *
982
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
983
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
984
     */
985
    public function testUpdateLocationWithSameRemoteId()
986
    {
987
        $repository = $this->getRepository();
988
989
        $locationId = $this->generateId('location', 5);
990
        /* BEGIN: Use Case */
991
        // $locationId and remote ID is the IDs of the same, existing location
992
        $locationService = $repository->getLocationService();
993
994
        $originalLocation = $locationService->loadLocation($locationId);
995
996
        $updateStruct = $locationService->newLocationUpdateStruct();
997
998
        // Remote ID of an existing location with the same locationId
999
        $updateStruct->remoteId = $originalLocation->remoteId;
1000
1001
        // Sets one of the properties to be able to confirm location gets updated, here: priority
1002
        $updateStruct->priority = 2;
1003
1004
        $location = $locationService->updateLocation($originalLocation, $updateStruct);
1005
1006
        // Checks that the location was updated
1007
        $this->assertEquals(2, $location->priority);
1008
1009
        // Checks that remoteId remains the same
1010
        $this->assertEquals($originalLocation->remoteId, $location->remoteId);
1011
        /* END: Use Case */
1012
    }
1013
1014
    /**
1015
     * Test for the updateLocation() method.
1016
     *
1017
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1018
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1019
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1020
     */
1021 View Code Duplication
    public function testUpdateLocationThrowsInvalidArgumentException()
1022
    {
1023
        $repository = $this->getRepository();
1024
1025
        $locationId = $this->generateId('location', 5);
1026
        /* BEGIN: Use Case */
1027
        // $locationId and remoteId is the IDs of an existing, but not the same, location
1028
        $locationService = $repository->getLocationService();
1029
1030
        $originalLocation = $locationService->loadLocation($locationId);
1031
1032
        $updateStruct = $locationService->newLocationUpdateStruct();
1033
1034
        // Remote ID of an existing location with a different locationId
1035
        $updateStruct->remoteId = 'f3e90596361e31d496d4026eb624c983';
1036
1037
        // Throws exception, since remote ID is already taken
1038
        $locationService->updateLocation($originalLocation, $updateStruct);
1039
        /* END: Use Case */
1040
    }
1041
1042
    /**
1043
     * Test for the updateLocation() method.
1044
     * Ref EZP-23302: Update Location fails if no change is performed with the update.
1045
     *
1046
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1047
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1048
     */
1049
    public function testUpdateLocationTwice()
1050
    {
1051
        $repository = $this->getRepository();
1052
1053
        $locationId = $this->generateId('location', 5);
1054
        /* BEGIN: Use Case */
1055
        $locationService = $repository->getLocationService();
1056
        $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...
1057
1058
        $originalLocation = $locationService->loadLocation($locationId);
1059
1060
        $updateStruct = $locationService->newLocationUpdateStruct();
1061
        $updateStruct->priority = 42;
1062
1063
        $updatedLocation = $locationService->updateLocation($originalLocation, $updateStruct);
1064
1065
        // Repeated update with the same, unchanged struct
1066
        $secondUpdatedLocation = $locationService->updateLocation($updatedLocation, $updateStruct);
1067
        /* END: Use Case */
1068
1069
        $this->assertEquals($updatedLocation->priority, 42);
1070
        $this->assertEquals($secondUpdatedLocation->priority, 42);
1071
    }
1072
1073
    /**
1074
     * Test for the swapLocation() method.
1075
     *
1076
     * @see \eZ\Publish\API\Repository\LocationService::swapLocation()
1077
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1078
     */
1079
    public function testSwapLocation()
1080
    {
1081
        $repository = $this->getRepository();
1082
        $locationService = $repository->getLocationService();
1083
1084
        $mediaLocationId = $this->generateId('location', 43);
1085
        $demoDesignLocationId = $this->generateId('location', 56);
1086
1087
        $mediaContentInfo = $locationService->loadLocation($mediaLocationId)->getContentInfo();
1088
        $demoDesignContentInfo = $locationService->loadLocation($demoDesignLocationId)->getContentInfo();
1089
1090
        /* BEGIN: Use Case */
1091
        // $mediaLocationId is the ID of the "Media" page location in
1092
        // an eZ Publish demo installation
1093
1094
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1095
        // Publish demo installation
1096
1097
        // Load the location service
1098
        $locationService = $repository->getLocationService();
1099
1100
        $mediaLocation = $locationService->loadLocation($mediaLocationId);
1101
        $demoDesignLocation = $locationService->loadLocation($demoDesignLocationId);
1102
1103
        // Swaps the content referred to by the locations
1104
        $locationService->swapLocation($mediaLocation, $demoDesignLocation);
1105
        /* END: Use Case */
1106
1107
        // Reload Locations, IDs swapped
1108
        $demoDesignLocation = $locationService->loadLocation($mediaLocationId);
1109
        $mediaLocation = $locationService->loadLocation($demoDesignLocationId);
1110
1111
        // Assert Location's Content is updated
1112
        $this->assertEquals(
1113
            $mediaContentInfo->id,
1114
            $mediaLocation->getContentInfo()->id
1115
        );
1116
        $this->assertEquals(
1117
            $demoDesignContentInfo->id,
1118
            $demoDesignLocation->getContentInfo()->id
1119
        );
1120
1121
        // Assert URL aliases are updated
1122
        $this->assertEquals(
1123
            $mediaLocation->id,
1124
            $repository->getURLAliasService()->lookup('/Design/Media')->destination
1125
        );
1126
        $this->assertEquals(
1127
            $demoDesignLocation->id,
1128
            $repository->getURLAliasService()->lookup('/eZ-Publish-Demo-Design-without-demo-content')->destination
1129
        );
1130
    }
1131
1132
    /**
1133
     * Test swapping secondary Location with main Location.
1134
     *
1135
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1136
     *
1137
     * @see https://jira.ez.no/browse/EZP-28663
1138
     *
1139
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1140
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1141
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1142
     *
1143
     * @return int[]
1144
     */
1145
    public function testSwapLocationForMainAndSecondaryLocation()
1146
    {
1147
        $repository = $this->getRepository();
1148
        $locationService = $repository->getLocationService();
1149
        $contentService = $repository->getContentService();
1150
1151
        $folder1 = $this->createFolder(['eng-GB' => 'Folder1'], 2);
1152
        $folder2 = $this->createFolder(['eng-GB' => 'Folder2'], 2);
1153
        $folder3 = $this->createFolder(['eng-GB' => 'Folder3'], 2);
1154
1155
        $primaryLocation = $locationService->loadLocation($folder1->contentInfo->mainLocationId);
1156
        $parentLocation = $locationService->loadLocation($folder2->contentInfo->mainLocationId);
1157
        $secondaryLocation = $locationService->createLocation(
1158
            $folder1->contentInfo,
1159
            $locationService->newLocationCreateStruct($parentLocation->id)
1160
        );
1161
1162
        $targetLocation = $locationService->loadLocation($folder3->contentInfo->mainLocationId);
1163
1164
        // perform sanity checks
1165
        $folder1Locations = $locationService->loadLocations($folder1->contentInfo);
1166
        self::assertCount(2, $folder1Locations);
1167
        self::assertContains(
1168
            $primaryLocation,
1169
            $folder1Locations,
1170
            "Location {$primaryLocation->id} not found in Folder1 Locations",
1171
            false,
1172
            false
1173
        );
1174
        self::assertContains(
1175
            $secondaryLocation,
1176
            $folder1Locations,
1177
            "Location {$secondaryLocation->id} not found in Folder1 Locations",
1178
            false,
1179
            false
1180
        );
1181
1182
        // begin use case
1183
        $locationService->swapLocation($secondaryLocation, $targetLocation);
1184
1185
        // test results
1186
        $primaryLocation = $locationService->loadLocation($primaryLocation->id);
1187
        $secondaryLocation = $locationService->loadLocation($secondaryLocation->id);
1188
        $targetLocation = $locationService->loadLocation($targetLocation->id);
1189
1190
        self::assertEquals($folder1->id, $primaryLocation->contentInfo->id);
1191
        self::assertEquals($folder1->id, $targetLocation->contentInfo->id);
1192
        self::assertEquals($folder3->id, $secondaryLocation->contentInfo->id);
1193
1194
        $folder1Locations = $locationService->loadLocations($folder1->contentInfo);
1195
        self::assertCount(2, $folder1Locations);
1196
        self::assertContains(
1197
            $primaryLocation,
1198
            $folder1Locations,
1199
            "Location {$primaryLocation->id} not found in Folder1 Locations",
1200
            false,
1201
            false
1202
        );
1203
        self::assertContains(
1204
            $targetLocation,
1205
            $folder1Locations,
1206
            "Location {$targetLocation->id} not found in Folder1 Locations",
1207
            false,
1208
            false
1209
        );
1210
1211
        self::assertEquals(
1212
            $folder1,
1213
            $contentService->loadContent($folder1->id)
1214
        );
1215
1216
        self::assertEquals(
1217
            $folder2,
1218
            $contentService->loadContent($folder2->id)
1219
        );
1220
1221
        // only in case of Folder 3, main location id changed due to swap
1222
        self::assertEquals(
1223
            $secondaryLocation->id,
1224
            $contentService->loadContent($folder3->id)->contentInfo->mainLocationId
1225
        );
1226
1227
        return [$folder1, $folder2, $folder3];
1228
    }
1229
1230
    /**
1231
     * @depends testSwapLocationForMainAndSecondaryLocation
1232
     *
1233
     * @param \eZ\Publish\API\Repository\Values\Content\Content[] $contentItems Content items created by testSwapLocationForSecondaryLocation
1234
     *
1235
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1236
     */
1237
    public function testSwapLocationDoesNotCorruptSearchResults(
1238
        array $contentItems
1239
    ) {
1240
        $repository = $this->getRepository(false);
1241
        $searchService = $repository->getSearchService();
1242
1243
        $this->refreshSearch($repository);
1244
1245
        $contentIds = array_map(
1246
            function (Content $content) {
1247
                return $content->id;
1248
            },
1249
            $contentItems
1250
        );
1251
1252
        $query = new Query();
1253
        $query->filter = new Query\Criterion\ContentId($contentIds);
1254
1255
        $searchResult = $searchService->findContent($query);
1256
1257
        self::assertEquals(count($contentItems), $searchResult->totalCount);
1258
        self::assertEquals(
1259
            $searchResult->totalCount,
1260
            count($searchResult->searchHits),
1261
            'Total count of search result hits does not match the actual number of found results'
1262
        );
1263
        $foundContentIds = array_map(
1264
            function (SearchHit $searchHit) {
1265
                return $searchHit->valueObject->id;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1266
            },
1267
            $searchResult->searchHits
1268
        );
1269
        sort($contentIds);
1270
        sort($foundContentIds);
1271
        self::assertSame(
1272
            $contentIds,
1273
            $foundContentIds,
1274
            'Got different than expected Content item Ids'
1275
        );
1276
    }
1277
1278
    /**
1279
     * Test swapping two secondary (non-main) Locations.
1280
     *
1281
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1282
     *
1283
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1284
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1285
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1286
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1287
     */
1288
    public function testSwapLocationForSecondaryLocations()
1289
    {
1290
        $repository = $this->getRepository();
1291
        $locationService = $repository->getLocationService();
1292
        $contentService = $repository->getContentService();
1293
1294
        $folder1 = $this->createFolder(['eng-GB' => 'Folder1'], 2);
1295
        $folder2 = $this->createFolder(['eng-GB' => 'Folder2'], 2);
1296
        $parentFolder1 = $this->createFolder(['eng-GB' => 'Parent1'], 2);
1297
        $parentFolder2 = $this->createFolder(['eng-GB' => 'Parent2'], 2);
1298
1299
        $parentLocation1 = $locationService->loadLocation($parentFolder1->contentInfo->mainLocationId);
1300
        $parentLocation2 = $locationService->loadLocation($parentFolder2->contentInfo->mainLocationId);
1301
        $secondaryLocation1 = $locationService->createLocation(
1302
            $folder1->contentInfo,
1303
            $locationService->newLocationCreateStruct($parentLocation1->id)
1304
        );
1305
        $secondaryLocation2 = $locationService->createLocation(
1306
            $folder2->contentInfo,
1307
            $locationService->newLocationCreateStruct($parentLocation2->id)
1308
        );
1309
1310
        // begin use case
1311
        $locationService->swapLocation($secondaryLocation1, $secondaryLocation2);
1312
1313
        // test results
1314
        $secondaryLocation1 = $locationService->loadLocation($secondaryLocation1->id);
1315
        $secondaryLocation2 = $locationService->loadLocation($secondaryLocation2->id);
1316
1317
        self::assertEquals($folder2->id, $secondaryLocation1->contentInfo->id);
1318
        self::assertEquals($folder1->id, $secondaryLocation2->contentInfo->id);
1319
1320
        self::assertEquals(
1321
            $folder1,
1322
            $contentService->loadContent($folder1->id)
1323
        );
1324
1325
        self::assertEquals(
1326
            $folder2,
1327
            $contentService->loadContent($folder2->id)
1328
        );
1329
    }
1330
1331
    /**
1332
     * Test for the hideLocation() method.
1333
     *
1334
     * @see \eZ\Publish\API\Repository\LocationService::hideLocation()
1335
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1336
     */
1337
    public function testHideLocation()
1338
    {
1339
        $repository = $this->getRepository();
1340
1341
        $locationId = $this->generateId('location', 5);
1342
        /* BEGIN: Use Case */
1343
        // $locationId is the ID of an existing location
1344
        $locationService = $repository->getLocationService();
1345
1346
        $visibleLocation = $locationService->loadLocation($locationId);
1347
1348
        $hiddenLocation = $locationService->hideLocation($visibleLocation);
1349
        /* END: Use Case */
1350
1351
        $this->assertInstanceOf(
1352
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1353
            $hiddenLocation
1354
        );
1355
1356
        $this->assertTrue(
1357
            $hiddenLocation->hidden,
1358
            sprintf(
1359
                'Location with ID "%s" not hidden.',
1360
                $hiddenLocation->id
1361
            )
1362
        );
1363
1364
        $this->refreshSearch($repository);
1365
1366
        foreach ($locationService->loadLocationChildren($hiddenLocation)->locations as $child) {
1367
            $this->assertSubtreeProperties(
1368
                array('invisible' => true),
1369
                $child
1370
            );
1371
        }
1372
    }
1373
1374
    /**
1375
     * Assert that $expectedValues are set in the subtree starting at $location.
1376
     *
1377
     * @param array $expectedValues
1378
     * @param Location $location
1379
     */
1380
    protected function assertSubtreeProperties(array $expectedValues, Location $location, $stopId = null)
1381
    {
1382
        $repository = $this->getRepository();
1383
        $locationService = $repository->getLocationService();
1384
1385
        if ($location->id === $stopId) {
1386
            return;
1387
        }
1388
1389
        foreach ($expectedValues as $propertyName => $propertyValue) {
1390
            $this->assertEquals(
1391
                $propertyValue,
1392
                $location->$propertyName
1393
            );
1394
1395
            foreach ($locationService->loadLocationChildren($location)->locations as $child) {
1396
                $this->assertSubtreeProperties($expectedValues, $child);
1397
            }
1398
        }
1399
    }
1400
1401
    /**
1402
     * Test for the unhideLocation() method.
1403
     *
1404
     * @see \eZ\Publish\API\Repository\LocationService::unhideLocation()
1405
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testHideLocation
1406
     */
1407
    public function testUnhideLocation()
1408
    {
1409
        $repository = $this->getRepository();
1410
1411
        $locationId = $this->generateId('location', 5);
1412
        /* BEGIN: Use Case */
1413
        // $locationId is the ID of an existing location
1414
        $locationService = $repository->getLocationService();
1415
1416
        $visibleLocation = $locationService->loadLocation($locationId);
1417
        $hiddenLocation = $locationService->hideLocation($visibleLocation);
1418
1419
        $unHiddenLocation = $locationService->unhideLocation($hiddenLocation);
1420
        /* END: Use Case */
1421
1422
        $this->assertInstanceOf(
1423
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1424
            $unHiddenLocation
1425
        );
1426
1427
        $this->assertFalse(
1428
            $unHiddenLocation->hidden,
1429
            sprintf(
1430
                'Location with ID "%s" not unhidden.',
1431
                $unHiddenLocation->id
1432
            )
1433
        );
1434
1435
        $this->refreshSearch($repository);
1436
1437
        foreach ($locationService->loadLocationChildren($unHiddenLocation)->locations as $child) {
1438
            $this->assertSubtreeProperties(
1439
                array('invisible' => false),
1440
                $child
1441
            );
1442
        }
1443
    }
1444
1445
    /**
1446
     * Test for the unhideLocation() method.
1447
     *
1448
     * @see \eZ\Publish\API\Repository\LocationService::unhideLocation()
1449
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testUnhideLocation
1450
     */
1451
    public function testUnhideLocationNotUnhidesHiddenSubtree()
1452
    {
1453
        $repository = $this->getRepository();
1454
1455
        $higherLocationId = $this->generateId('location', 5);
1456
        $lowerLocationId = $this->generateId('location', 13);
1457
        /* BEGIN: Use Case */
1458
        // $higherLocationId is the ID of a location
1459
        // $lowerLocationId is the ID of a location below $higherLocationId
1460
        $locationService = $repository->getLocationService();
1461
1462
        $higherLocation = $locationService->loadLocation($higherLocationId);
1463
        $hiddenHigherLocation = $locationService->hideLocation($higherLocation);
1464
1465
        $lowerLocation = $locationService->loadLocation($lowerLocationId);
1466
        $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...
1467
1468
        $unHiddenHigherLocation = $locationService->unhideLocation($hiddenHigherLocation);
1469
        /* END: Use Case */
1470
1471
        $this->assertInstanceOf(
1472
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1473
            $unHiddenHigherLocation
1474
        );
1475
1476
        $this->assertFalse(
1477
            $unHiddenHigherLocation->hidden,
1478
            sprintf(
1479
                'Location with ID "%s" not unhidden.',
1480
                $unHiddenHigherLocation->id
1481
            )
1482
        );
1483
1484
        $this->refreshSearch($repository);
1485
1486
        foreach ($locationService->loadLocationChildren($unHiddenHigherLocation)->locations as $child) {
1487
            $this->assertSubtreeProperties(
1488
                array('invisible' => false),
1489
                $child,
1490
                $this->generateId('location', 13)
1491
            );
1492
        }
1493
1494
        $stillHiddenLocation = $locationService->loadLocation($this->generateId('location', 13));
1495
        $this->assertTrue(
1496
            $stillHiddenLocation->hidden,
1497
            sprintf(
1498
                'Hidden sub-location with ID %s accidentally unhidden.',
1499
                $stillHiddenLocation->id
1500
            )
1501
        );
1502
        foreach ($locationService->loadLocationChildren($stillHiddenLocation)->locations as $child) {
1503
            $this->assertSubtreeProperties(
1504
                array('invisible' => true),
1505
                $child
1506
            );
1507
        }
1508
    }
1509
1510
    /**
1511
     * Test for the deleteLocation() method.
1512
     *
1513
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1514
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1515
     */
1516
    public function testDeleteLocation()
1517
    {
1518
        $repository = $this->getRepository();
1519
1520
        $mediaLocationId = $this->generateId('location', 43);
1521
        /* BEGIN: Use Case */
1522
        // $mediaLocationId is the ID of the location of the
1523
        // "Media" location in an eZ Publish demo installation
1524
        $locationService = $repository->getLocationService();
1525
1526
        $location = $locationService->loadLocation($mediaLocationId);
1527
1528
        $locationService->deleteLocation($location);
1529
        /* END: Use Case */
1530
1531
        try {
1532
            $locationService->loadLocation($mediaLocationId);
1533
            $this->fail("Location $mediaLocationId not deleted.");
1534
        } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1535
        }
1536
1537
        // The following IDs are IDs of child locations of $mediaLocationId location
1538
        // ( Media/Images, Media/Files, Media/Multimedia respectively )
1539
        foreach (array(51, 52, 53) as $childLocationId) {
1540
            try {
1541
                $locationService->loadLocation($this->generateId('location', $childLocationId));
1542
                $this->fail("Location $childLocationId not deleted.");
1543
            } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1544
            }
1545
        }
1546
1547
        // The following IDs are IDs of content below $mediaLocationId location
1548
        // ( Media/Images, Media/Files, Media/Multimedia respectively )
1549
        $contentService = $this->getRepository()->getContentService();
1550
        foreach (array(49, 50, 51) as $childContentId) {
1551
            try {
1552
                $contentService->loadContentInfo($this->generateId('object', $childContentId));
1553
                $this->fail("Content $childContentId not deleted.");
1554
            } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1555
            }
1556
        }
1557
    }
1558
1559
    /**
1560
     * Test for the deleteLocation() method.
1561
     *
1562
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1563
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testDeleteLocation
1564
     */
1565
    public function testDeleteLocationDecrementsChildCountOnParent()
1566
    {
1567
        $repository = $this->getRepository();
1568
1569
        $mediaLocationId = $this->generateId('location', 43);
1570
        /* BEGIN: Use Case */
1571
        // $mediaLocationId is the ID of the location of the
1572
        // "Media" location in an eZ Publish demo installation
1573
1574
        $locationService = $repository->getLocationService();
1575
1576
        // Load the current the user group location
1577
        $location = $locationService->loadLocation($mediaLocationId);
1578
1579
        // Load the parent location
1580
        $parentLocation = $locationService->loadLocation(
1581
            $location->parentLocationId
1582
        );
1583
1584
        // Get child count
1585
        $childCountBefore = $locationService->getLocationChildCount($parentLocation);
1586
1587
        // Delete the user group location
1588
        $locationService->deleteLocation($location);
1589
1590
        $this->refreshSearch($repository);
1591
1592
        // Reload parent location
1593
        $parentLocation = $locationService->loadLocation(
1594
            $location->parentLocationId
1595
        );
1596
1597
        // This will be $childCountBefore - 1
1598
        $childCountAfter = $locationService->getLocationChildCount($parentLocation);
1599
        /* END: Use Case */
1600
1601
        $this->assertEquals($childCountBefore - 1, $childCountAfter);
1602
    }
1603
1604
    /**
1605
     * Test for the deleteLocation() method.
1606
     *
1607
     * Related issue: EZP-21904
1608
     *
1609
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1610
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1611
     */
1612
    public function testDeleteContentObjectLastLocation()
1613
    {
1614
        $repository = $this->getRepository();
1615
1616
        /* BEGIN: Use case */
1617
        $contentService = $repository->getContentService();
1618
        $locationService = $repository->getLocationService();
1619
        $contentTypeService = $repository->getContentTypeService();
1620
        $urlAliasService = $repository->getURLAliasService();
1621
1622
        // prepare Content object
1623
        $createStruct = $contentService->newContentCreateStruct(
1624
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1625
            'eng-GB'
1626
        );
1627
        $createStruct->setField('name', 'Test folder');
1628
1629
        // creata Content object
1630
        $content = $contentService->publishVersion(
1631
            $contentService->createContent(
1632
                $createStruct,
1633
                array($locationService->newLocationCreateStruct(2))
1634
            )->versionInfo
1635
        );
1636
1637
        // delete location
1638
        $locationService->deleteLocation(
1639
            $locationService->loadLocation(
1640
                $urlAliasService->lookup('/Test-folder')->destination
1641
            )
1642
        );
1643
1644
        // this should throw a not found exception
1645
        $contentService->loadContent($content->versionInfo->contentInfo->id);
1646
        /* END: Use case*/
1647
    }
1648
1649
    /**
1650
     * Test for the copySubtree() method.
1651
     *
1652
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1653
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1654
     */
1655
    public function testCopySubtree()
1656
    {
1657
        $repository = $this->getRepository();
1658
1659
        $mediaLocationId = $this->generateId('location', 43);
1660
        $demoDesignLocationId = $this->generateId('location', 56);
1661
        /* BEGIN: Use Case */
1662
        // $mediaLocationId is the ID of the "Media" page location in
1663
        // an eZ Publish demo installation
1664
1665
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1666
        // Publish demo installation
1667
1668
        // Load the location service
1669
        $locationService = $repository->getLocationService();
1670
1671
        // Load location to copy
1672
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1673
1674
        // Load new parent location
1675
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1676
1677
        // Copy location "Media" to "Demo Design"
1678
        $copiedLocation = $locationService->copySubtree(
1679
            $locationToCopy,
1680
            $newParentLocation
1681
        );
1682
        /* END: Use Case */
1683
1684
        $this->assertInstanceOf(
1685
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1686
            $copiedLocation
1687
        );
1688
1689
        $this->assertPropertiesCorrect(
1690
            array(
1691
                'depth' => $newParentLocation->depth + 1,
1692
                'parentLocationId' => $newParentLocation->id,
1693
                'pathString' => "{$newParentLocation->pathString}" . $this->parseId('location', $copiedLocation->id) . '/',
1694
            ),
1695
            $copiedLocation
1696
        );
1697
1698
        $this->assertDefaultContentStates($copiedLocation->contentInfo);
1699
    }
1700
1701
    /**
1702
     * Test for the copySubtree() method.
1703
     *
1704
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1705
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1706
     */
1707
    public function testCopySubtreeWithAliases()
1708
    {
1709
        $repository = $this->getRepository();
1710
        $urlAliasService = $repository->getURLAliasService();
1711
1712
        // $mediaLocationId is the ID of the "Media" page location in
1713
        // an eZ Publish demo installation
1714
1715
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1716
        // Publish demo installation
1717
        $mediaLocationId = $this->generateId('location', 43);
1718
        $demoDesignLocationId = $this->generateId('location', 56);
1719
1720
        $locationService = $repository->getLocationService();
1721
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1722
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1723
1724
        $expectedSubItemAliases = [
1725
            '/Design/Plain-site/Media/Multimedia',
1726
            '/Design/Plain-site/Media/Images',
1727
            '/Design/Plain-site/Media/Files',
1728
        ];
1729
1730
        $this->assertAliasesBeforeCopy($urlAliasService, $expectedSubItemAliases);
1731
1732
        // Copy location "Media" to "Design"
1733
        $locationService->copySubtree(
1734
            $locationToCopy,
1735
            $newParentLocation
1736
        );
1737
1738
        $this->assertGeneratedAliases($urlAliasService, $expectedSubItemAliases);
1739
    }
1740
1741
    /**
1742
     * Asserts that given Content has default ContentStates.
1743
     *
1744
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
1745
     */
1746 View Code Duplication
    private function assertDefaultContentStates(ContentInfo $contentInfo)
1747
    {
1748
        $repository = $this->getRepository();
1749
        $objectStateService = $repository->getObjectStateService();
1750
1751
        $objectStateGroups = $objectStateService->loadObjectStateGroups();
1752
1753
        foreach ($objectStateGroups as $objectStateGroup) {
1754
            $contentState = $objectStateService->getContentState($contentInfo, $objectStateGroup);
1755
            foreach ($objectStateService->loadObjectStates($objectStateGroup) as $objectState) {
1756
                // Only check the first object state which is the default one.
1757
                $this->assertEquals(
1758
                    $objectState,
1759
                    $contentState
1760
                );
1761
                break;
1762
            }
1763
        }
1764
    }
1765
1766
    /**
1767
     * Test for the copySubtree() method.
1768
     *
1769
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1770
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
1771
     */
1772
    public function testCopySubtreeUpdatesSubtreeProperties()
1773
    {
1774
        $repository = $this->getRepository();
1775
        $locationService = $repository->getLocationService();
1776
1777
        $locationToCopy = $locationService->loadLocation($this->generateId('location', 43));
1778
1779
        // Load Subtree properties before copy
1780
        $expected = $this->loadSubtreeProperties($locationToCopy);
1781
1782
        $mediaLocationId = $this->generateId('location', 43);
1783
        $demoDesignLocationId = $this->generateId('location', 56);
1784
        /* BEGIN: Use Case */
1785
        // $mediaLocationId is the ID of the "Media" page location in
1786
        // an eZ Publish demo installation
1787
1788
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1789
        // Publish demo installation
1790
1791
        // Load the location service
1792
        $locationService = $repository->getLocationService();
1793
1794
        // Load location to copy
1795
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1796
1797
        // Load new parent location
1798
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1799
1800
        // Copy location "Media" to "Demo Design"
1801
        $copiedLocation = $locationService->copySubtree(
1802
            $locationToCopy,
1803
            $newParentLocation
1804
        );
1805
        /* END: Use Case */
1806
1807
        $beforeIds = array();
1808
        foreach ($expected as $properties) {
1809
            $beforeIds[] = $properties['id'];
1810
        }
1811
1812
        $this->refreshSearch($repository);
1813
1814
        // Load Subtree properties after copy
1815
        $actual = $this->loadSubtreeProperties($copiedLocation);
1816
1817
        $this->assertEquals(count($expected), count($actual));
1818
1819
        foreach ($actual as $properties) {
1820
            $this->assertNotContains($properties['id'], $beforeIds);
1821
            $this->assertStringStartsWith(
1822
                "{$newParentLocation->pathString}" . $this->parseId('location', $copiedLocation->id) . '/',
1823
                $properties['pathString']
1824
            );
1825
            $this->assertStringEndsWith(
1826
                '/' . $this->parseId('location', $properties['id']) . '/',
1827
                $properties['pathString']
1828
            );
1829
        }
1830
    }
1831
1832
    /**
1833
     * Test for the copySubtree() method.
1834
     *
1835
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1836
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
1837
     */
1838
    public function testCopySubtreeIncrementsChildCountOfNewParent()
1839
    {
1840
        $repository = $this->getRepository();
1841
        $locationService = $repository->getLocationService();
1842
1843
        $childCountBefore = $locationService->getLocationChildCount($locationService->loadLocation(56));
1844
1845
        $mediaLocationId = $this->generateId('location', 43);
1846
        $demoDesignLocationId = $this->generateId('location', 56);
1847
        /* BEGIN: Use Case */
1848
        // $mediaLocationId is the ID of the "Media" page location in
1849
        // an eZ Publish demo installation
1850
1851
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1852
        // Publish demo installation
1853
1854
        // Load the location service
1855
        $locationService = $repository->getLocationService();
1856
1857
        // Load location to copy
1858
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1859
1860
        // Load new parent location
1861
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1862
1863
        // Copy location "Media" to "Demo Design"
1864
        $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...
1865
            $locationToCopy,
1866
            $newParentLocation
1867
        );
1868
        /* END: Use Case */
1869
1870
        $this->refreshSearch($repository);
1871
1872
        $childCountAfter = $locationService->getLocationChildCount($locationService->loadLocation($demoDesignLocationId));
1873
1874
        $this->assertEquals($childCountBefore + 1, $childCountAfter);
1875
    }
1876
1877
    /**
1878
     * Test for the copySubtree() method.
1879
     *
1880
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1881
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1882
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
1883
     */
1884 View Code Duplication
    public function testCopySubtreeThrowsInvalidArgumentException()
1885
    {
1886
        $repository = $this->getRepository();
1887
1888
        $communityLocationId = $this->generateId('location', 5);
1889
        /* BEGIN: Use Case */
1890
        // $communityLocationId is the ID of the "Community" page location in
1891
        // an eZ Publish demo installation
1892
1893
        // Load the location service
1894
        $locationService = $repository->getLocationService();
1895
1896
        // Load location to copy
1897
        $locationToCopy = $locationService->loadLocation($communityLocationId);
1898
1899
        // Use a child as new parent
1900
        $childLocations = $locationService->loadLocationChildren($locationToCopy)->locations;
1901
        $newParentLocation = end($childLocations);
1902
1903
        // This call will fail with an "InvalidArgumentException", because the
1904
        // new parent is a child location of the subtree to copy.
1905
        $locationService->copySubtree(
1906
            $locationToCopy,
1907
            $newParentLocation
0 ignored issues
show
Security Bug introduced by
It seems like $newParentLocation defined by end($childLocations) on line 1901 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...
1908
        );
1909
        /* END: Use Case */
1910
    }
1911
1912
    /**
1913
     * Test for the moveSubtree() method.
1914
     *
1915
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
1916
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1917
     */
1918
    public function testMoveSubtree()
1919
    {
1920
        $repository = $this->getRepository();
1921
1922
        $mediaLocationId = $this->generateId('location', 43);
1923
        $demoDesignLocationId = $this->generateId('location', 56);
1924
        /* BEGIN: Use Case */
1925
        // $mediaLocationId is the ID of the "Media" page location in
1926
        // an eZ Publish demo installation
1927
1928
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1929
        // Publish demo installation
1930
1931
        // Load the location service
1932
        $locationService = $repository->getLocationService();
1933
1934
        // Load location to move
1935
        $locationToMove = $locationService->loadLocation($mediaLocationId);
1936
1937
        // Load new parent location
1938
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1939
1940
        // Move location from "Home" to "Demo Design"
1941
        $locationService->moveSubtree(
1942
            $locationToMove,
1943
            $newParentLocation
1944
        );
1945
1946
        // Load moved location
1947
        $movedLocation = $locationService->loadLocation($mediaLocationId);
1948
        /* END: Use Case */
1949
1950
        $this->assertPropertiesCorrect(
1951
            array(
1952
                'hidden' => false,
1953
                'invisible' => false,
1954
                'depth' => $newParentLocation->depth + 1,
1955
                'parentLocationId' => $newParentLocation->id,
1956
                'pathString' => "{$newParentLocation->pathString}" . $this->parseId('location', $movedLocation->id) . '/',
1957
            ),
1958
            $movedLocation
1959
        );
1960
    }
1961
1962
    /**
1963
     * Test for the moveSubtree() method.
1964
     *
1965
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
1966
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
1967
     */
1968
    public function testMoveSubtreeHidden()
1969
    {
1970
        $repository = $this->getRepository();
1971
1972
        $mediaLocationId = $this->generateId('location', 43);
1973
        $demoDesignLocationId = $this->generateId('location', 56);
1974
        /* BEGIN: Use Case */
1975
        // $mediaLocationId is the ID of the "Media" page location in
1976
        // an eZ Publish demo installation
1977
1978
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1979
        // Publish demo installation
1980
1981
        // Load the location service
1982
        $locationService = $repository->getLocationService();
1983
1984
        // Load location to move
1985
        $locationToMove = $locationService->loadLocation($mediaLocationId);
1986
1987
        // Load new parent location
1988
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1989
1990
        // Hide the target location before we move
1991
        $newParentLocation = $locationService->hideLocation($newParentLocation);
1992
1993
        // Move location from "Home" to "Demo Design"
1994
        $locationService->moveSubtree(
1995
            $locationToMove,
1996
            $newParentLocation
1997
        );
1998
1999
        // Load moved location
2000
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2001
        /* END: Use Case */
2002
2003
        $this->assertPropertiesCorrect(
2004
            array(
2005
                'hidden' => false,
2006
                'invisible' => true,
2007
                'depth' => $newParentLocation->depth + 1,
2008
                'parentLocationId' => $newParentLocation->id,
2009
                'pathString' => "{$newParentLocation->pathString}" . $this->parseId('location', $movedLocation->id) . '/',
2010
            ),
2011
            $movedLocation
2012
        );
2013
    }
2014
2015
    /**
2016
     * Test for the moveSubtree() method.
2017
     *
2018
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2019
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2020
     */
2021
    public function testMoveSubtreeUpdatesSubtreeProperties()
2022
    {
2023
        $repository = $this->getRepository();
2024
        $locationService = $repository->getLocationService();
2025
2026
        $locationToMove = $locationService->loadLocation($this->generateId('location', 43));
2027
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2028
2029
        // Load Subtree properties before move
2030
        $expected = $this->loadSubtreeProperties($locationToMove);
2031
        foreach ($expected as $id => $properties) {
2032
            $expected[$id]['depth'] = $properties['depth'] + 2;
2033
            $expected[$id]['pathString'] = str_replace(
2034
                $locationToMove->pathString,
2035
                "{$newParentLocation->pathString}" . $this->parseId('location', $locationToMove->id) . '/',
2036
                $properties['pathString']
2037
            );
2038
        }
2039
2040
        $mediaLocationId = $this->generateId('location', 43);
2041
        $demoDesignLocationId = $this->generateId('location', 56);
2042
        /* BEGIN: Use Case */
2043
        // $mediaLocationId is the ID of the "Media" page location in
2044
        // an eZ Publish demo installation
2045
2046
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2047
        // Publish demo installation
2048
2049
        // Load the location service
2050
        $locationService = $repository->getLocationService();
2051
2052
        // Load location to move
2053
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2054
2055
        // Load new parent location
2056
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2057
2058
        // Move location from "Home" to "Demo Design"
2059
        $locationService->moveSubtree(
2060
            $locationToMove,
2061
            $newParentLocation
2062
        );
2063
2064
        // Load moved location
2065
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2066
        /* END: Use Case */
2067
2068
        $this->refreshSearch($repository);
2069
2070
        // Load Subtree properties after move
2071
        $actual = $this->loadSubtreeProperties($movedLocation);
2072
2073
        $this->assertEquals($expected, $actual);
2074
    }
2075
2076
    /**
2077
     * Test for the moveSubtree() method.
2078
     *
2079
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2080
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtreeUpdatesSubtreeProperties
2081
     */
2082
    public function testMoveSubtreeUpdatesSubtreePropertiesHidden()
2083
    {
2084
        $repository = $this->getRepository();
2085
        $locationService = $repository->getLocationService();
2086
2087
        $locationToMove = $locationService->loadLocation($this->generateId('location', 43));
2088
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2089
2090
        // Hide the target location before we move
2091
        $newParentLocation = $locationService->hideLocation($newParentLocation);
2092
2093
        // Load Subtree properties before move
2094
        $expected = $this->loadSubtreeProperties($locationToMove);
2095
        foreach ($expected as $id => $properties) {
2096
            $expected[$id]['invisible'] = true;
2097
            $expected[$id]['depth'] = $properties['depth'] + 2;
2098
            $expected[$id]['pathString'] = str_replace(
2099
                $locationToMove->pathString,
2100
                "{$newParentLocation->pathString}" . $this->parseId('location', $locationToMove->id) . '/',
2101
                $properties['pathString']
2102
            );
2103
        }
2104
2105
        $mediaLocationId = $this->generateId('location', 43);
2106
        $demoDesignLocationId = $this->generateId('location', 56);
2107
        /* BEGIN: Use Case */
2108
        // $mediaLocationId is the ID of the "Media" page location in
2109
        // an eZ Publish demo installation
2110
2111
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2112
        // Publish demo installation
2113
2114
        // Load the location service
2115
        $locationService = $repository->getLocationService();
2116
2117
        // Load location to move
2118
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2119
2120
        // Load new parent location
2121
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2122
2123
        // Move location from "Home" to "Demo Design"
2124
        $locationService->moveSubtree(
2125
            $locationToMove,
2126
            $newParentLocation
2127
        );
2128
2129
        // Load moved location
2130
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2131
        /* END: Use Case */
2132
2133
        $this->refreshSearch($repository);
2134
2135
        // Load Subtree properties after move
2136
        $actual = $this->loadSubtreeProperties($movedLocation);
2137
2138
        $this->assertEquals($expected, $actual);
2139
    }
2140
2141
    /**
2142
     * Test for the moveSubtree() method.
2143
     *
2144
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2145
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2146
     */
2147 View Code Duplication
    public function testMoveSubtreeIncrementsChildCountOfNewParent()
2148
    {
2149
        $repository = $this->getRepository();
2150
        $locationService = $repository->getLocationService();
2151
2152
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2153
2154
        // Load expected properties before move
2155
        $expected = $this->loadLocationProperties($newParentLocation);
2156
        $childCountBefore = $locationService->getLocationChildCount($newParentLocation);
2157
2158
        $mediaLocationId = $this->generateId('location', 43);
2159
        $demoDesignLocationId = $this->generateId('location', 56);
2160
        /* BEGIN: Use Case */
2161
        // $mediaLocationId is the ID of the "Media" page location in
2162
        // an eZ Publish demo installation
2163
2164
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2165
        // Publish demo installation
2166
2167
        // Load the location service
2168
        $locationService = $repository->getLocationService();
2169
2170
        // Load location to move
2171
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2172
2173
        // Load new parent location
2174
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2175
2176
        // Move location from "Home" to "Demo Design"
2177
        $locationService->moveSubtree(
2178
            $locationToMove,
2179
            $newParentLocation
2180
        );
2181
2182
        // Load moved location
2183
        $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...
2184
2185
        // Reload new parent location
2186
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2187
        /* END: Use Case */
2188
2189
        $this->refreshSearch($repository);
2190
2191
        // Load Subtree properties after move
2192
        $actual = $this->loadLocationProperties($newParentLocation);
2193
        $childCountAfter = $locationService->getLocationChildCount($newParentLocation);
2194
2195
        $this->assertEquals($expected, $actual);
2196
        $this->assertEquals($childCountBefore + 1, $childCountAfter);
2197
    }
2198
2199
    /**
2200
     * Test for the moveSubtree() method.
2201
     *
2202
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2203
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2204
     */
2205 View Code Duplication
    public function testMoveSubtreeDecrementsChildCountOfOldParent()
2206
    {
2207
        $repository = $this->getRepository();
2208
        $locationService = $repository->getLocationService();
2209
2210
        $oldParentLocation = $locationService->loadLocation($this->generateId('location', 1));
2211
2212
        // Load expected properties before move
2213
        $expected = $this->loadLocationProperties($oldParentLocation);
2214
        $childCountBefore = $locationService->getLocationChildCount($oldParentLocation);
2215
2216
        $mediaLocationId = $this->generateId('location', 43);
2217
        $demoDesignLocationId = $this->generateId('location', 56);
2218
        /* BEGIN: Use Case */
2219
        // $mediaLocationId is the ID of the "Media" page location in
2220
        // an eZ Publish demo installation
2221
2222
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2223
        // Publish demo installation
2224
2225
        // Load the location service
2226
        $locationService = $repository->getLocationService();
2227
2228
        // Load location to move
2229
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2230
2231
        // Get the location id of the old parent
2232
        $oldParentLocationId = $locationToMove->parentLocationId;
2233
2234
        // Load new parent location
2235
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2236
2237
        // Move location from "Home" to "Demo Design"
2238
        $locationService->moveSubtree(
2239
            $locationToMove,
2240
            $newParentLocation
2241
        );
2242
2243
        // Reload old parent location
2244
        $oldParentLocation = $locationService->loadLocation($oldParentLocationId);
2245
        /* END: Use Case */
2246
2247
        $this->refreshSearch($repository);
2248
2249
        // Load Subtree properties after move
2250
        $actual = $this->loadLocationProperties($oldParentLocation);
2251
        $childCountAfter = $locationService->getLocationChildCount($oldParentLocation);
2252
2253
        $this->assertEquals($expected, $actual);
2254
        $this->assertEquals($childCountBefore - 1, $childCountAfter);
2255
    }
2256
2257
    /**
2258
     * Test moving invisible (hidden by parent) subtree.
2259
     *
2260
     * @covers \eZ\Publish\API\Repository\LocationService::moveSubtree
2261
     *
2262
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
2263
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
2264
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
2265
     */
2266
    public function testMoveInvisibleSubtree()
2267
    {
2268
        $repository = $this->getRepository();
2269
        $locationService = $repository->getLocationService();
2270
2271
        $rootLocationId = 2;
2272
2273
        $folder = $this->createFolder(['eng-GB' => 'Folder'], $rootLocationId);
2274
        $child = $this->createFolder(['eng-GB' => 'Child'], $folder->contentInfo->mainLocationId);
2275
        $locationService->hideLocation(
2276
            $locationService->loadLocation($folder->contentInfo->mainLocationId)
2277
        );
2278
        // sanity check
2279
        $childLocation = $locationService->loadLocation($child->contentInfo->mainLocationId);
2280
        self::assertFalse($childLocation->hidden);
2281
        self::assertTrue($childLocation->invisible);
2282
        self::assertEquals($folder->contentInfo->mainLocationId, $childLocation->parentLocationId);
2283
2284
        $destination = $this->createFolder(['eng-GB' => 'Destination'], $rootLocationId);
2285
        $destinationLocation = $locationService->loadLocation(
2286
            $destination->contentInfo->mainLocationId
2287
        );
2288
2289
        $locationService->moveSubtree($childLocation, $destinationLocation);
2290
2291
        $childLocation = $locationService->loadLocation($child->contentInfo->mainLocationId);
2292
        // Business logic - Location moved to visible parent becomes visible
2293
        self::assertFalse($childLocation->hidden);
2294
        self::assertFalse($childLocation->invisible);
2295
        self::assertEquals($destinationLocation->id, $childLocation->parentLocationId);
2296
    }
2297
2298
    /**
2299
     * Test for the moveSubtree() method.
2300
     *
2301
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2302
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2303
     */
2304 View Code Duplication
    public function testMoveSubtreeThrowsInvalidArgumentException()
2305
    {
2306
        $repository = $this->getRepository();
2307
        $mediaLocationId = $this->generateId('location', 43);
2308
        $multimediaLocationId = $this->generateId('location', 53);
2309
2310
        /* BEGIN: Use Case */
2311
        // $mediaLocationId is the ID of the "Media" page location in
2312
        // an eZ Publish demo installation
2313
2314
        // $multimediaLocationId is the ID of the "Multimedia" page location in an eZ
2315
        // Publish demo installation
2316
2317
        // Load the location service
2318
        $locationService = $repository->getLocationService();
2319
2320
        // Load location to move
2321
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2322
2323
        // Load new parent location
2324
        $newParentLocation = $locationService->loadLocation($multimediaLocationId);
2325
2326
        // Throws an exception because new parent location is placed below location to move
2327
        $locationService->moveSubtree(
2328
            $locationToMove,
2329
            $newParentLocation
2330
        );
2331
        /* END: Use Case */
2332
    }
2333
2334
    /**
2335
     * Loads properties from all locations in the $location's subtree.
2336
     *
2337
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
2338
     * @param array $properties
2339
     *
2340
     * @return array
2341
     */
2342
    private function loadSubtreeProperties(Location $location, array $properties = array())
2343
    {
2344
        $locationService = $this->getRepository()->getLocationService();
2345
2346
        foreach ($locationService->loadLocationChildren($location)->locations as $childLocation) {
2347
            $properties[] = $this->loadLocationProperties($childLocation);
2348
2349
            $properties = $this->loadSubtreeProperties($childLocation, $properties);
2350
        }
2351
2352
        return $properties;
2353
    }
2354
2355
    /**
2356
     * Loads assertable properties from the given location.
2357
     *
2358
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
2359
     * @param mixed[] $overwrite
2360
     *
2361
     * @return array
2362
     */
2363 View Code Duplication
    private function loadLocationProperties(Location $location, array $overwrite = array())
2364
    {
2365
        return array_merge(
2366
            array(
2367
                'id' => $location->id,
2368
                'depth' => $location->depth,
2369
                'parentLocationId' => $location->parentLocationId,
2370
                'pathString' => $location->pathString,
2371
                'remoteId' => $location->remoteId,
2372
                'hidden' => $location->hidden,
2373
                'invisible' => $location->invisible,
2374
                'priority' => $location->priority,
2375
                'sortField' => $location->sortField,
2376
                'sortOrder' => $location->sortOrder,
2377
            ),
2378
            $overwrite
2379
        );
2380
    }
2381
2382
    /**
2383
     * Assert generated aliases to expected alias return.
2384
     *
2385
     * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
2386
     * @param array $expectedAliases
2387
     */
2388
    protected function assertGeneratedAliases($urlAliasService, array $expectedAliases)
2389
    {
2390
        foreach ($expectedAliases as $expectedAlias) {
2391
            $urlAlias = $urlAliasService->lookup($expectedAlias);
2392
            $this->assertPropertiesCorrect(['type' => 0], $urlAlias);
2393
        }
2394
    }
2395
2396
    /**
2397
     * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
2398
     * @param array $expectedSubItemAliases
2399
     */
2400
    private function assertAliasesBeforeCopy($urlAliasService, array $expectedSubItemAliases)
2401
    {
2402
        foreach ($expectedSubItemAliases as $aliasUrl) {
2403
            try {
2404
                $urlAliasService->lookup($aliasUrl);
2405
                $this->fail('We didn\'t expect to find alias, but it was found');
2406
            } catch (\Exception $e) {
2407
                $this->assertTrue(true); // OK - alias was not found
2408
            }
2409
        }
2410
    }
2411
}
2412