Completed
Push — 7.3 ( 3059b7...a9e484 )
by André
159:32 queued 133:40
created

LocationServiceTest::testMoveInvisibleSubtree()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 31
rs 9.424
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\BadStateException;
13
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
14
use eZ\Publish\API\Repository\Values\Content\Content;
15
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
16
use eZ\Publish\API\Repository\Values\Content\Location;
17
use eZ\Publish\API\Repository\Values\Content\LocationCreateStruct;
18
use eZ\Publish\API\Repository\Values\Content\LocationList;
19
use eZ\Publish\API\Repository\Values\Content\LocationUpdateStruct;
20
use eZ\Publish\API\Repository\Values\Content\Query;
21
use eZ\Publish\API\Repository\Values\Content\Search\SearchHit;
22
23
/**
24
 * Test case for operations in the LocationService using in memory storage.
25
 *
26
 * @see eZ\Publish\API\Repository\LocationService
27
 * @group location
28
 */
29
class LocationServiceTest extends BaseTest
30
{
31
    /**
32
     * Test for the newLocationCreateStruct() method.
33
     *
34
     * @return \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct
35
     *
36
     * @see \eZ\Publish\API\Repository\LocationService::newLocationCreateStruct()
37
     */
38
    public function testNewLocationCreateStruct()
39
    {
40
        $repository = $this->getRepository();
41
42
        $parentLocationId = $this->generateId('location', 1);
43
        /* BEGIN: Use Case */
44
        // $parentLocationId is the ID of an existing location
45
        $locationService = $repository->getLocationService();
46
47
        $locationCreate = $locationService->newLocationCreateStruct(
48
            $parentLocationId
49
        );
50
        /* END: Use Case */
51
52
        $this->assertInstanceOf(
53
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationCreateStruct',
54
            $locationCreate
55
        );
56
57
        return $locationCreate;
58
    }
59
60
    /**
61
     * Test for the newLocationCreateStruct() method.
62
     *
63
     * @param \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct $locationCreate
64
     *
65
     * @see \eZ\Publish\API\Repository\LocationService::newLocationCreateStruct()
66
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
67
     */
68
    public function testNewLocationCreateStructValues(LocationCreateStruct $locationCreate)
69
    {
70
        $this->assertPropertiesCorrect(
71
            array(
72
                'priority' => 0,
73
                'hidden' => false,
74
                // remoteId should be initialized with a default value
75
                //'remoteId' => null,
76
                'sortField' => Location::SORT_FIELD_NAME,
77
                'sortOrder' => Location::SORT_ORDER_ASC,
78
                'parentLocationId' => $this->generateId('location', 1),
79
            ),
80
            $locationCreate
81
        );
82
    }
83
84
    /**
85
     * Test for the createLocation() method.
86
     *
87
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
88
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
89
     */
90
    public function testCreateLocation()
91
    {
92
        $repository = $this->getRepository();
93
94
        $contentId = $this->generateId('object', 41);
95
        $parentLocationId = $this->generateId('location', 5);
96
        /* BEGIN: Use Case */
97
        // $contentId is the ID of an existing content object
98
        // $parentLocationId is the ID of an existing location
99
        $contentService = $repository->getContentService();
100
        $locationService = $repository->getLocationService();
101
102
        // ContentInfo for "How to use eZ Publish"
103
        $contentInfo = $contentService->loadContentInfo($contentId);
104
105
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
106
        $locationCreate->priority = 23;
107
        $locationCreate->hidden = true;
108
        $locationCreate->remoteId = 'sindelfingen';
109
        $locationCreate->sortField = Location::SORT_FIELD_NODE_ID;
110
        $locationCreate->sortOrder = Location::SORT_ORDER_DESC;
111
112
        $location = $locationService->createLocation(
113
            $contentInfo,
114
            $locationCreate
115
        );
116
        /* END: Use Case */
117
118
        $this->assertInstanceOf(
119
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
120
            $location
121
        );
122
123
        return array(
124
            'locationCreate' => $locationCreate,
125
            'createdLocation' => $location,
126
            'contentInfo' => $contentInfo,
127
            'parentLocation' => $locationService->loadLocation($this->generateId('location', 5)),
128
        );
129
    }
130
131
    /**
132
     * Test for the createLocation() method.
133
     *
134
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
135
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
136
     */
137
    public function testCreateLocationStructValues(array $data)
138
    {
139
        $locationCreate = $data['locationCreate'];
140
        $createdLocation = $data['createdLocation'];
141
        $contentInfo = $data['contentInfo'];
142
143
        $this->assertPropertiesCorrect(
144
            array(
145
                'priority' => $locationCreate->priority,
146
                'hidden' => $locationCreate->hidden,
147
                'invisible' => $locationCreate->hidden,
148
                'remoteId' => $locationCreate->remoteId,
149
                'contentInfo' => $contentInfo,
150
                'parentLocationId' => $locationCreate->parentLocationId,
151
                'pathString' => '/1/5/' . $this->parseId('location', $createdLocation->id) . '/',
152
                'depth' => 2,
153
                'sortField' => $locationCreate->sortField,
154
                'sortOrder' => $locationCreate->sortOrder,
155
            ),
156
            $createdLocation
157
        );
158
159
        $this->assertNotNull($createdLocation->id);
160
    }
161
162
    /**
163
     * Test for the createLocation() method.
164
     *
165
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
166
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
167
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
168
     */
169 View Code Duplication
    public function testCreateLocationThrowsInvalidArgumentExceptionContentAlreadyBelowParent()
170
    {
171
        $repository = $this->getRepository();
172
173
        $contentId = $this->generateId('object', 11);
174
        $parentLocationId = $this->generateId('location', 5);
175
        /* BEGIN: Use Case */
176
        // $contentId is the ID of an existing content object
177
        // $parentLocationId is the ID of an existing location which already
178
        // has the content assigned to one of its descendant locations
179
        $contentService = $repository->getContentService();
180
        $locationService = $repository->getLocationService();
181
182
        // ContentInfo for "How to use eZ Publish"
183
        $contentInfo = $contentService->loadContentInfo($contentId);
184
185
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
186
187
        // Throws exception, since content is already located at "/1/2/107/110/"
188
        $locationService->createLocation(
189
            $contentInfo,
190
            $locationCreate
191
        );
192
        /* END: Use Case */
193
    }
194
195
    /**
196
     * Test for the createLocation() method.
197
     *
198
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
199
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
200
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
201
     */
202 View Code Duplication
    public function testCreateLocationThrowsInvalidArgumentExceptionParentIsSubLocationOfContent()
203
    {
204
        $repository = $this->getRepository();
205
206
        $contentId = $this->generateId('object', 4);
207
        $parentLocationId = $this->generateId('location', 12);
208
        /* BEGIN: Use Case */
209
        // $contentId is the ID of an existing content object
210
        // $parentLocationId is the ID of an existing location which is below a
211
        // location that is assigned to the content
212
        $contentService = $repository->getContentService();
213
        $locationService = $repository->getLocationService();
214
215
        // ContentInfo for "How to use eZ Publish"
216
        $contentInfo = $contentService->loadContentInfo($contentId);
217
218
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
219
220
        // Throws exception, since content is already located at "/1/2/"
221
        $locationService->createLocation(
222
            $contentInfo,
223
            $locationCreate
224
        );
225
        /* END: Use Case */
226
    }
227
228
    /**
229
     * Test for the createLocation() method.
230
     *
231
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
232
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
233
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
234
     */
235 View Code Duplication
    public function testCreateLocationThrowsInvalidArgumentExceptionRemoteIdExists()
236
    {
237
        $repository = $this->getRepository();
238
239
        $contentId = $this->generateId('object', 41);
240
        $parentLocationId = $this->generateId('location', 5);
241
        /* BEGIN: Use Case */
242
        // $contentId is the ID of an existing content object
243
        $contentService = $repository->getContentService();
244
        $locationService = $repository->getLocationService();
245
246
        // ContentInfo for "How to use eZ Publish"
247
        $contentInfo = $contentService->loadContentInfo($contentId);
248
249
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
250
        // This remote ID already exists
251
        $locationCreate->remoteId = 'f3e90596361e31d496d4026eb624c983';
252
253
        // Throws exception, since remote ID is already in use
254
        $locationService->createLocation(
255
            $contentInfo,
256
            $locationCreate
257
        );
258
        /* END: Use Case */
259
    }
260
261
    /**
262
     * Test for the createLocation() method.
263
     *
264
     * @covers \eZ\Publish\API\Repository\LocationService::createLocation()
265
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
266
     * @dataProvider dataProviderForOutOfRangeLocationPriority
267
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
268
     */
269 View Code Duplication
    public function testCreateLocationThrowsInvalidArgumentExceptionPriorityIsOutOfRange($priority)
270
    {
271
        $repository = $this->getRepository();
272
273
        $contentId = $this->generateId('object', 41);
274
        $parentLocationId = $this->generateId('location', 5);
275
        /* BEGIN: Use Case */
276
        // $contentId is the ID of an existing content object
277
        // $parentLocationId is the ID of an existing location
278
        $contentService = $repository->getContentService();
279
        $locationService = $repository->getLocationService();
280
281
        // ContentInfo for "How to use eZ Publish"
282
        $contentInfo = $contentService->loadContentInfo($contentId);
283
284
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
285
        $locationCreate->priority = $priority;
286
        $locationCreate->hidden = true;
287
        $locationCreate->remoteId = 'sindelfingen';
288
        $locationCreate->sortField = Location::SORT_FIELD_NODE_ID;
289
        $locationCreate->sortOrder = Location::SORT_ORDER_DESC;
290
291
        // Throws exception, since priority is out of range
292
        $locationService->createLocation(
293
            $contentInfo,
294
            $locationCreate
295
        );
296
        /* END: Use Case */
297
    }
298
299
    public function dataProviderForOutOfRangeLocationPriority()
300
    {
301
        return [[-2147483649], [2147483648]];
302
    }
303
304
    /**
305
     * Test for the createLocation() method.
306
     *
307
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
308
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
309
     */
310
    public function testCreateLocationInTransactionWithRollback()
311
    {
312
        $repository = $this->getRepository();
313
314
        $contentId = $this->generateId('object', 41);
315
        $parentLocationId = $this->generateId('location', 5);
316
        /* BEGIN: Use Case */
317
        // $contentId is the ID of an existing content object
318
        // $parentLocationId is the ID of an existing location
319
        $contentService = $repository->getContentService();
320
        $locationService = $repository->getLocationService();
321
322
        $repository->beginTransaction();
323
324
        try {
325
            // ContentInfo for "How to use eZ Publish"
326
            $contentInfo = $contentService->loadContentInfo($contentId);
327
328
            $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
329
            $locationCreate->remoteId = 'sindelfingen';
330
331
            $createdLocationId = $locationService->createLocation(
332
                $contentInfo,
333
                $locationCreate
334
            )->id;
335
        } catch (Exception $e) {
336
            // Cleanup hanging transaction on error
337
            $repository->rollback();
338
            throw $e;
339
        }
340
341
        $repository->rollback();
342
343
        try {
344
            // Throws exception since creation of location was rolled back
345
            $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...
346
        } catch (NotFoundException $e) {
347
            return;
348
        }
349
        /* END: Use Case */
350
351
        $this->fail('Objects still exists after rollback.');
352
    }
353
354
    /**
355
     * Test for the loadLocation() method.
356
     *
357
     * @return \eZ\Publish\API\Repository\Values\Content\Location
358
     *
359
     * @covers \eZ\Publish\API\Repository\LocationService::loadLocation
360
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
361
     */
362
    public function testLoadLocation()
363
    {
364
        $repository = $this->getRepository();
365
366
        $locationId = $this->generateId('location', 5);
367
        /* BEGIN: Use Case */
368
        // $locationId is the ID of an existing location
369
        $locationService = $repository->getLocationService();
370
371
        $location = $locationService->loadLocation($locationId);
372
        /* END: Use Case */
373
374
        $this->assertInstanceOf(
375
            Location::class,
376
            $location
377
        );
378
        self::assertEquals(5, $location->id);
379
380
        return $location;
381
    }
382
383
    /**
384
     * Test for the loadLocation() method.
385
     *
386
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
387
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
388
     */
389
    public function testLoadLocationRootStructValues()
390
    {
391
        $repository = $this->getRepository();
392
        $locationService = $repository->getLocationService();
393
        $location = $locationService->loadLocation($this->generateId('location', 1));
394
395
        $legacyDateTime = new \DateTime();
396
        $legacyDateTime->setTimestamp(1030968000);
397
398
        // $location
399
        $this->assertPropertiesCorrect(
400
            array(
401
                'id' => $this->generateId('location', 1),
402
                'status' => 1,
403
                'priority' => 0,
404
                'hidden' => false,
405
                'invisible' => false,
406
                'remoteId' => '629709ba256fe317c3ddcee35453a96a',
407
                'parentLocationId' => $this->generateId('location', 1),
408
                'pathString' => '/1/',
409
                'depth' => 0,
410
                'sortField' => 1,
411
                'sortOrder' => 1,
412
            ),
413
            $location
414
        );
415
416
        // $location->contentInfo
417
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $location->contentInfo);
418
        $this->assertPropertiesCorrect(
419
            array(
420
                'id' => $this->generateId('content', 0),
421
                'name' => 'Top Level Nodes',
422
                'sectionId' => 1,
423
                'mainLocationId' => 1,
424
                'contentTypeId' => 1,
425
                'currentVersionNo' => 1,
426
                'published' => 1,
427
                'ownerId' => 14,
428
                'modificationDate' => $legacyDateTime,
429
                'publishedDate' => $legacyDateTime,
430
                'alwaysAvailable' => 1,
431
                'remoteId' => null,
432
                'mainLanguageCode' => 'eng-GB',
433
            ),
434
            $location->contentInfo
435
        );
436
    }
437
438
    /**
439
     * Test for the loadLocation() method.
440
     *
441
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
442
     *
443
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
444
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
445
     */
446
    public function testLoadLocationStructValues(Location $location)
447
    {
448
        $this->assertPropertiesCorrect(
449
            array(
450
                'id' => $this->generateId('location', 5),
451
                'priority' => 0,
452
                'hidden' => false,
453
                'invisible' => false,
454
                'remoteId' => '3f6d92f8044aed134f32153517850f5a',
455
                'parentLocationId' => $this->generateId('location', 1),
456
                'pathString' => '/1/5/',
457
                'depth' => 1,
458
                'sortField' => 1,
459
                'sortOrder' => 1,
460
            ),
461
            $location
462
        );
463
464
        $this->assertInstanceOf(
465
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo',
466
            $location->contentInfo
467
        );
468
        $this->assertEquals($this->generateId('object', 4), $location->contentInfo->id);
469
470
        // Check lazy loaded proxy on ->content
471
        $this->assertInstanceOf(
472
            Content::class,
473
            $content = $location->getContent()
474
        );
475
        $this->assertEquals(4, $content->contentInfo->id);
476
    }
477
478
    public function testLoadLocationPrioritizedLanguagesFallback()
479
    {
480
        $repository = $this->getRepository();
481
482
        // Add a language
483
        $this->createLanguage('nor-NO', 'Norsk');
484
485
        $locationService = $repository->getLocationService();
486
        $contentService = $repository->getContentService();
487
        $location = $locationService->loadLocation(5);
488
489
        // Translate "Users"
490
        $draft = $contentService->createContentDraft($location->contentInfo);
491
        $struct = $contentService->newContentUpdateStruct();
492
        $struct->setField('name', 'Brukere', 'nor-NO');
493
        $draft = $contentService->updateContent($draft->getVersionInfo(), $struct);
494
        $contentService->publishVersion($draft->getVersionInfo());
495
496
        // Load with priority language (fallback will be the old one)
497
        $location = $locationService->loadLocation(5, ['nor-NO']);
498
499
        $this->assertInstanceOf(
500
            Location::class,
501
            $location
502
        );
503
        self::assertEquals(5, $location->id);
504
        $this->assertInstanceOf(
505
            Content::class,
506
            $content = $location->getContent()
507
        );
508
        $this->assertEquals(4, $content->contentInfo->id);
509
510
        $this->assertEquals($content->getVersionInfo()->getName(), 'Brukere');
511
        $this->assertEquals($content->getVersionInfo()->getName('eng-US'), 'Users');
512
    }
513
514
    /**
515
     * Test that accessing lazy-loaded Content without a translation in the specific
516
     * not available language throws NotFoundException.
517
     */
518
    public function testLoadLocationThrowsNotFoundExceptionForNotAvailableContent(): void
519
    {
520
        $repository = $this->getRepository();
521
522
        $locationService = $repository->getLocationService();
523
524
        $this->createLanguage('pol-PL', 'Polski');
525
526
        $this->expectException(NotFoundException::class);
527
528
        // Note: relying on existing database fixtures to make test case more readable
529
        $locationService->loadLocation(60, ['pol-PL']);
530
    }
531
532
    /**
533
     * Test for the loadLocation() method.
534
     *
535
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
536
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
537
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
538
     */
539
    public function testLoadLocationThrowsNotFoundException()
540
    {
541
        $repository = $this->getRepository();
542
543
        $nonExistentLocationId = $this->generateId('location', 2342);
544
        /* BEGIN: Use Case */
545
        $locationService = $repository->getLocationService();
546
547
        // Throws exception, if Location with $nonExistentLocationId does not
548
        // exist
549
        $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...
550
        /* END: Use Case */
551
    }
552
553
    /**
554
     * Test for the loadLocationByRemoteId() method.
555
     *
556
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationByRemoteId()
557
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
558
     */
559 View Code Duplication
    public function testLoadLocationByRemoteId()
560
    {
561
        $repository = $this->getRepository();
562
563
        /* BEGIN: Use Case */
564
        $locationService = $repository->getLocationService();
565
566
        $location = $locationService->loadLocationByRemoteId(
567
            '3f6d92f8044aed134f32153517850f5a'
568
        );
569
        /* END: Use Case */
570
571
        $this->assertEquals(
572
            $locationService->loadLocation($this->generateId('location', 5)),
573
            $location
574
        );
575
    }
576
577
    /**
578
     * Test for the loadLocationByRemoteId() method.
579
     *
580
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationByRemoteId()
581
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
582
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
583
     */
584
    public function testLoadLocationByRemoteIdThrowsNotFoundException()
585
    {
586
        $repository = $this->getRepository();
587
588
        /* BEGIN: Use Case */
589
        $locationService = $repository->getLocationService();
590
591
        // Throws exception, since Location with remote ID does not exist
592
        $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...
593
            'not-exists'
594
        );
595
        /* END: Use Case */
596
    }
597
598
    /**
599
     * Test for the loadLocations() method.
600
     *
601
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
602
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
603
     */
604
    public function testLoadLocations()
605
    {
606
        $repository = $this->getRepository();
607
608
        $contentId = $this->generateId('object', 4);
609
        /* BEGIN: Use Case */
610
        // $contentId contains the ID of an existing content object
611
        $contentService = $repository->getContentService();
612
        $locationService = $repository->getLocationService();
613
614
        $contentInfo = $contentService->loadContentInfo($contentId);
615
616
        $locations = $locationService->loadLocations($contentInfo);
617
        /* END: Use Case */
618
619
        $this->assertInternalType('array', $locations);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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...
620
        self::assertNotEmpty($locations);
621
622
        foreach ($locations as $location) {
623
            self::assertInstanceOf(Location::class, $location);
624
            self::assertEquals($contentInfo->id, $location->getContentInfo()->id);
625
        }
626
627
        return $locations;
628
    }
629
630
    /**
631
     * Test for the loadLocations() method.
632
     *
633
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
634
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
635
     */
636
    public function testLoadLocationsContent(array $locations)
637
    {
638
        $repository = $this->getRepository();
639
        $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...
640
641
        $this->assertEquals(1, count($locations));
642
        foreach ($locations as $loadedLocation) {
643
            $this->assertInstanceOf(
644
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
645
                $loadedLocation
646
            );
647
        }
648
649
        usort(
650
            $locations,
651
            function ($a, $b) {
652
                strcmp($a->id, $b->id);
653
            }
654
        );
655
656
        $this->assertEquals(
657
            array($this->generateId('location', 5)),
658
            array_map(
659
                function (Location $location) {
660
                    return $location->id;
661
                },
662
                $locations
663
            )
664
        );
665
    }
666
667
    /**
668
     * Test for the loadLocations() method.
669
     *
670
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
671
     *
672
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations($contentInfo, $rootLocation)
673
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
674
     */
675
    public function testLoadLocationsLimitedSubtree()
676
    {
677
        $repository = $this->getRepository();
678
679
        $originalLocationId = $this->generateId('location', 54);
680
        $originalParentLocationId = $this->generateId('location', 48);
681
        $newParentLocationId = $this->generateId('location', 43);
682
        /* BEGIN: Use Case */
683
        // $originalLocationId is the ID of an existing location
684
        // $originalParentLocationId is the ID of the parent location of
685
        //     $originalLocationId
686
        // $newParentLocationId is the ID of an existing location outside the tree
687
        // of $originalLocationId and $originalParentLocationId
688
        $locationService = $repository->getLocationService();
689
690
        // Location at "/1/48/54"
691
        $originalLocation = $locationService->loadLocation($originalLocationId);
692
693
        // Create location under "/1/43/"
694
        $locationCreate = $locationService->newLocationCreateStruct($newParentLocationId);
695
        $locationService->createLocation(
696
            $originalLocation->contentInfo,
697
            $locationCreate
698
        );
699
700
        $findRootLocation = $locationService->loadLocation($originalParentLocationId);
701
702
        // Returns an array with only $originalLocation
703
        $locations = $locationService->loadLocations(
704
            $originalLocation->contentInfo,
705
            $findRootLocation
706
        );
707
        /* END: Use Case */
708
709
        $this->assertInternalType('array', $locations);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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...
710
711
        return $locations;
712
    }
713
714
    /**
715
     * Test for the loadLocations() method.
716
     *
717
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
718
     *
719
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
720
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationsLimitedSubtree
721
     */
722
    public function testLoadLocationsLimitedSubtreeContent(array $locations)
723
    {
724
        $this->assertEquals(1, count($locations));
725
726
        $this->assertEquals(
727
            $this->generateId('location', 54),
728
            reset($locations)->id
729
        );
730
    }
731
732
    /**
733
     * Test for the loadLocations() method.
734
     *
735
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
736
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
737
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
738
     */
739 View Code Duplication
    public function testLoadLocationsThrowsBadStateException()
740
    {
741
        $repository = $this->getRepository();
742
743
        /* BEGIN: Use Case */
744
        $contentTypeService = $repository->getContentTypeService();
745
        $contentService = $repository->getContentService();
746
        $locationService = $repository->getLocationService();
747
748
        // Create new content, which is not published
749
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
750
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
751
        $contentCreate->setField('name', 'New Folder');
752
        $content = $contentService->createContent($contentCreate);
753
754
        // Throws Exception, since $content has no published version, yet
755
        $locationService->loadLocations(
756
            $content->contentInfo
757
        );
758
        /* END: Use Case */
759
    }
760
761
    /**
762
     * Test for the loadLocations() method.
763
     *
764
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations($contentInfo, $rootLocation)
765
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
766
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
767
     */
768
    public function testLoadLocationsThrowsBadStateExceptionLimitedSubtree()
769
    {
770
        $repository = $this->getRepository();
771
772
        $someLocationId = $this->generateId('location', 2);
773
        /* BEGIN: Use Case */
774
        // $someLocationId is the ID of an existing location
775
        $contentTypeService = $repository->getContentTypeService();
776
        $contentService = $repository->getContentService();
777
        $locationService = $repository->getLocationService();
778
779
        // Create new content, which is not published
780
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
781
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
782
        $contentCreate->setField('name', 'New Folder');
783
        $content = $contentService->createContent($contentCreate);
784
785
        $findRootLocation = $locationService->loadLocation($someLocationId);
786
787
        // Throws Exception, since $content has no published version, yet
788
        $locationService->loadLocations(
789
            $content->contentInfo,
790
            $findRootLocation
791
        );
792
        /* END: Use Case */
793
    }
794
795
    /**
796
     * Test for the loadLocationChildren() method.
797
     *
798
     * @covers \eZ\Publish\API\Repository\LocationService::loadLocationChildren
799
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
800
     */
801
    public function testLoadLocationChildren()
802
    {
803
        $repository = $this->getRepository();
804
805
        $locationId = $this->generateId('location', 5);
806
        /* BEGIN: Use Case */
807
        // $locationId is the ID of an existing location
808
        $locationService = $repository->getLocationService();
809
810
        $location = $locationService->loadLocation($locationId);
811
812
        $childLocations = $locationService->loadLocationChildren($location);
813
        /* END: Use Case */
814
815
        $this->assertInstanceOf(LocationList::class, $childLocations);
816
        $this->assertInternalType('array', $childLocations->locations);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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...
817
        $this->assertNotEmpty($childLocations->locations);
818
        $this->assertInternalType('int', $childLocations->totalCount);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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...
819
820
        foreach ($childLocations->locations as $childLocation) {
821
            $this->assertInstanceOf(Location::class, $childLocation);
822
            $this->assertEquals($location->id, $childLocation->parentLocationId);
823
        }
824
825
        return $childLocations;
826
    }
827
828
    /**
829
     * Test loading parent Locations for draft Content.
830
     *
831
     * @covers \eZ\Publish\API\Repository\LocationService::loadParentLocationsForDraftContent
832
     */
833
    public function testLoadParentLocationsForDraftContent()
834
    {
835
        $repository = $this->getRepository();
836
        $locationService = $repository->getLocationService();
837
        $contentService = $repository->getContentService();
838
        $contentTypeService = $repository->getContentTypeService();
839
840
        // prepare locations
841
        $locationCreateStructs = [
842
            $locationService->newLocationCreateStruct(2),
843
            $locationService->newLocationCreateStruct(5),
844
        ];
845
846
        // Create new content
847
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
848
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
849
        $contentCreate->setField('name', 'New Folder');
850
        $contentDraft = $contentService->createContent($contentCreate, $locationCreateStructs);
851
852
        // Test loading parent Locations
853
        $locations = $locationService->loadParentLocationsForDraftContent($contentDraft->versionInfo);
854
855
        self::assertCount(2, $locations);
856
        foreach ($locations as $location) {
857
            // test it is one of the given parent locations
858
            self::assertTrue($location->id === 2 || $location->id === 5);
859
        }
860
861
        return $contentDraft;
862
    }
863
864
    /**
865
     * Test that trying to load parent Locations throws Exception if Content is not a draft.
866
     *
867
     * @depends testLoadParentLocationsForDraftContent
868
     *
869
     * @param \eZ\Publish\API\Repository\Values\Content\Content $contentDraft
870
     */
871
    public function testLoadParentLocationsForDraftContentThrowsBadStateException(Content $contentDraft)
872
    {
873
        $this->expectException(BadStateException::class);
874
        $this->expectExceptionMessageRegExp('/has been already published/');
875
876
        $repository = $this->getRepository(false);
877
        $locationService = $repository->getLocationService();
878
        $contentService = $repository->getContentService();
879
880
        $content = $contentService->publishVersion($contentDraft->versionInfo);
881
882
        $locationService->loadParentLocationsForDraftContent($content->versionInfo);
883
    }
884
885
    /**
886
     * Test for the getLocationChildCount() method.
887
     *
888
     * @see \eZ\Publish\API\Repository\LocationService::getLocationChildCount()
889
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
890
     */
891
    public function testGetLocationChildCount()
892
    {
893
        // $locationId is the ID of an existing location
894
        $locationService = $this->getRepository()->getLocationService();
895
896
        $this->assertSame(
897
            5,
898
            $locationService->getLocationChildCount(
899
                $locationService->loadLocation($this->generateId('location', 5))
900
            )
901
        );
902
    }
903
904
    /**
905
     * Test for the loadLocationChildren() method.
906
     *
907
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren()
908
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
909
     */
910
    public function testLoadLocationChildrenData(LocationList $locations)
911
    {
912
        $this->assertEquals(5, count($locations->locations));
913
        $this->assertEquals(5, $locations->totalCount);
914
915
        foreach ($locations->locations as $location) {
916
            $this->assertInstanceOf(
917
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
918
                $location
919
            );
920
        }
921
922
        $this->assertEquals(
923
            array(
924
                $this->generateId('location', 12),
925
                $this->generateId('location', 13),
926
                $this->generateId('location', 14),
927
                $this->generateId('location', 44),
928
                $this->generateId('location', 61),
929
            ),
930
            array_map(
931
                function (Location $location) {
932
                    return $location->id;
933
                },
934
                $locations->locations
935
            )
936
        );
937
    }
938
939
    /**
940
     * Test for the loadLocationChildren() method.
941
     *
942
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
943
     *
944
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset)
945
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
946
     */
947 View Code Duplication
    public function testLoadLocationChildrenWithOffset()
948
    {
949
        $repository = $this->getRepository();
950
951
        $locationId = $this->generateId('location', 5);
952
        /* BEGIN: Use Case */
953
        // $locationId is the ID of an existing location
954
        $locationService = $repository->getLocationService();
955
956
        $location = $locationService->loadLocation($locationId);
957
958
        $childLocations = $locationService->loadLocationChildren($location, 2);
959
        /* END: Use Case */
960
961
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
962
        $this->assertInternalType('array', $childLocations->locations);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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...
963
        $this->assertInternalType('int', $childLocations->totalCount);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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...
964
965
        return $childLocations;
966
    }
967
968
    /**
969
     * Test for the loadLocationChildren() method.
970
     *
971
     * @param \eZ\Publish\API\Repository\Values\Content\LocationList $locations
972
     *
973
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset)
974
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildrenWithOffset
975
     */
976 View Code Duplication
    public function testLoadLocationChildrenDataWithOffset(LocationList $locations)
977
    {
978
        $this->assertEquals(3, count($locations->locations));
979
        $this->assertEquals(5, $locations->totalCount);
980
981
        foreach ($locations->locations as $location) {
982
            $this->assertInstanceOf(
983
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
984
                $location
985
            );
986
        }
987
988
        $this->assertEquals(
989
            array(
990
                $this->generateId('location', 14),
991
                $this->generateId('location', 44),
992
                $this->generateId('location', 61),
993
            ),
994
            array_map(
995
                function (Location $location) {
996
                    return $location->id;
997
                },
998
                $locations->locations
999
            )
1000
        );
1001
    }
1002
1003
    /**
1004
     * Test for the loadLocationChildren() method.
1005
     *
1006
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
1007
     *
1008
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset, $limit)
1009
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
1010
     */
1011 View Code Duplication
    public function testLoadLocationChildrenWithOffsetAndLimit()
1012
    {
1013
        $repository = $this->getRepository();
1014
1015
        $locationId = $this->generateId('location', 5);
1016
        /* BEGIN: Use Case */
1017
        // $locationId is the ID of an existing location
1018
        $locationService = $repository->getLocationService();
1019
1020
        $location = $locationService->loadLocation($locationId);
1021
1022
        $childLocations = $locationService->loadLocationChildren($location, 2, 2);
1023
        /* END: Use Case */
1024
1025
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
1026
        $this->assertInternalType('array', $childLocations->locations);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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...
1027
        $this->assertInternalType('int', $childLocations->totalCount);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

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...
1028
1029
        return $childLocations;
1030
    }
1031
1032
    /**
1033
     * Test for the loadLocationChildren() method.
1034
     *
1035
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
1036
     *
1037
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset, $limit)
1038
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildrenWithOffsetAndLimit
1039
     */
1040 View Code Duplication
    public function testLoadLocationChildrenDataWithOffsetAndLimit(LocationList $locations)
1041
    {
1042
        $this->assertEquals(2, count($locations->locations));
1043
        $this->assertEquals(5, $locations->totalCount);
1044
1045
        foreach ($locations->locations as $location) {
1046
            $this->assertInstanceOf(
1047
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1048
                $location
1049
            );
1050
        }
1051
1052
        $this->assertEquals(
1053
            array(
1054
                $this->generateId('location', 14),
1055
                $this->generateId('location', 44),
1056
            ),
1057
            array_map(
1058
                function (Location $location) {
1059
                    return $location->id;
1060
                },
1061
                $locations->locations
1062
            )
1063
        );
1064
    }
1065
1066
    /**
1067
     * Test for the newLocationUpdateStruct() method.
1068
     *
1069
     * @covers \eZ\Publish\API\Repository\LocationService::newLocationUpdateStruct
1070
     */
1071 View Code Duplication
    public function testNewLocationUpdateStruct()
1072
    {
1073
        $repository = $this->getRepository();
1074
1075
        /* BEGIN: Use Case */
1076
        $locationService = $repository->getLocationService();
1077
1078
        $updateStruct = $locationService->newLocationUpdateStruct();
1079
        /* END: Use Case */
1080
1081
        $this->assertInstanceOf(
1082
            LocationUpdateStruct::class,
1083
            $updateStruct
1084
        );
1085
1086
        $this->assertPropertiesCorrect(
1087
            [
1088
                'priority' => null,
1089
                'remoteId' => null,
1090
                'sortField' => null,
1091
                'sortOrder' => null,
1092
            ],
1093
            $updateStruct
1094
        );
1095
    }
1096
1097
    /**
1098
     * Test for the updateLocation() method.
1099
     *
1100
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1101
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1102
     */
1103
    public function testUpdateLocation()
1104
    {
1105
        $repository = $this->getRepository();
1106
1107
        $originalLocationId = $this->generateId('location', 5);
1108
        /* BEGIN: Use Case */
1109
        // $originalLocationId is the ID of an existing location
1110
        $locationService = $repository->getLocationService();
1111
1112
        $originalLocation = $locationService->loadLocation($originalLocationId);
1113
1114
        $updateStruct = $locationService->newLocationUpdateStruct();
1115
        $updateStruct->priority = 3;
1116
        $updateStruct->remoteId = 'c7adcbf1e96bc29bca28c2d809d0c7ef69272651';
1117
        $updateStruct->sortField = Location::SORT_FIELD_PRIORITY;
1118
        $updateStruct->sortOrder = Location::SORT_ORDER_DESC;
1119
1120
        $updatedLocation = $locationService->updateLocation($originalLocation, $updateStruct);
1121
        /* END: Use Case */
1122
1123
        $this->assertInstanceOf(
1124
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1125
            $updatedLocation
1126
        );
1127
1128
        return array(
1129
            'originalLocation' => $originalLocation,
1130
            'updateStruct' => $updateStruct,
1131
            'updatedLocation' => $updatedLocation,
1132
        );
1133
    }
1134
1135
    /**
1136
     * Test for the updateLocation() method.
1137
     *
1138
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1139
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testUpdateLocation
1140
     */
1141
    public function testUpdateLocationStructValues(array $data)
1142
    {
1143
        $originalLocation = $data['originalLocation'];
1144
        $updateStruct = $data['updateStruct'];
1145
        $updatedLocation = $data['updatedLocation'];
1146
1147
        $this->assertPropertiesCorrect(
1148
            array(
1149
                'id' => $originalLocation->id,
1150
                'priority' => $updateStruct->priority,
1151
                'hidden' => $originalLocation->hidden,
1152
                'invisible' => $originalLocation->invisible,
1153
                'remoteId' => $updateStruct->remoteId,
1154
                'contentInfo' => $originalLocation->contentInfo,
1155
                'parentLocationId' => $originalLocation->parentLocationId,
1156
                'pathString' => $originalLocation->pathString,
1157
                'depth' => $originalLocation->depth,
1158
                'sortField' => $updateStruct->sortField,
1159
                'sortOrder' => $updateStruct->sortOrder,
1160
            ),
1161
            $updatedLocation
1162
        );
1163
    }
1164
1165
    /**
1166
     * Test for the updateLocation() method.
1167
     *
1168
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1169
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1170
     */
1171
    public function testUpdateLocationWithSameRemoteId()
1172
    {
1173
        $repository = $this->getRepository();
1174
1175
        $locationId = $this->generateId('location', 5);
1176
        /* BEGIN: Use Case */
1177
        // $locationId and remote ID is the IDs of the same, existing location
1178
        $locationService = $repository->getLocationService();
1179
1180
        $originalLocation = $locationService->loadLocation($locationId);
1181
1182
        $updateStruct = $locationService->newLocationUpdateStruct();
1183
1184
        // Remote ID of an existing location with the same locationId
1185
        $updateStruct->remoteId = $originalLocation->remoteId;
1186
1187
        // Sets one of the properties to be able to confirm location gets updated, here: priority
1188
        $updateStruct->priority = 2;
1189
1190
        $location = $locationService->updateLocation($originalLocation, $updateStruct);
1191
1192
        // Checks that the location was updated
1193
        $this->assertEquals(2, $location->priority);
1194
1195
        // Checks that remoteId remains the same
1196
        $this->assertEquals($originalLocation->remoteId, $location->remoteId);
1197
        /* END: Use Case */
1198
    }
1199
1200
    /**
1201
     * Test for the updateLocation() method.
1202
     *
1203
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1204
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1205
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1206
     */
1207 View Code Duplication
    public function testUpdateLocationThrowsInvalidArgumentException()
1208
    {
1209
        $repository = $this->getRepository();
1210
1211
        $locationId = $this->generateId('location', 5);
1212
        /* BEGIN: Use Case */
1213
        // $locationId and remoteId is the IDs of an existing, but not the same, location
1214
        $locationService = $repository->getLocationService();
1215
1216
        $originalLocation = $locationService->loadLocation($locationId);
1217
1218
        $updateStruct = $locationService->newLocationUpdateStruct();
1219
1220
        // Remote ID of an existing location with a different locationId
1221
        $updateStruct->remoteId = 'f3e90596361e31d496d4026eb624c983';
1222
1223
        // Throws exception, since remote ID is already taken
1224
        $locationService->updateLocation($originalLocation, $updateStruct);
1225
        /* END: Use Case */
1226
    }
1227
1228
    /**
1229
     * Test for the updateLocation() method.
1230
     *
1231
     * @covers \eZ\Publish\API\Repository\LocationService::updateLocation()
1232
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1233
     * @dataProvider dataProviderForOutOfRangeLocationPriority
1234
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1235
     */
1236
    public function testUpdateLocationThrowsInvalidArgumentExceptionPriorityIsOutOfRange($priority)
1237
    {
1238
        $repository = $this->getRepository();
1239
1240
        $locationId = $this->generateId('location', 5);
1241
        /* BEGIN: Use Case */
1242
        // $locationId and remoteId is the IDs of an existing, but not the same, location
1243
        $locationService = $repository->getLocationService();
1244
1245
        $originalLocation = $locationService->loadLocation($locationId);
1246
1247
        $updateStruct = $locationService->newLocationUpdateStruct();
1248
1249
        // Priority value is out of range
1250
        $updateStruct->priority = $priority;
1251
1252
        // Throws exception, since remote ID is already taken
1253
        $locationService->updateLocation($originalLocation, $updateStruct);
1254
        /* END: Use Case */
1255
    }
1256
1257
    /**
1258
     * Test for the updateLocation() method.
1259
     * Ref EZP-23302: Update Location fails if no change is performed with the update.
1260
     *
1261
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1262
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1263
     */
1264
    public function testUpdateLocationTwice()
1265
    {
1266
        $repository = $this->getRepository();
1267
1268
        $locationId = $this->generateId('location', 5);
1269
        /* BEGIN: Use Case */
1270
        $locationService = $repository->getLocationService();
1271
        $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...
1272
1273
        $originalLocation = $locationService->loadLocation($locationId);
1274
1275
        $updateStruct = $locationService->newLocationUpdateStruct();
1276
        $updateStruct->priority = 42;
1277
1278
        $updatedLocation = $locationService->updateLocation($originalLocation, $updateStruct);
1279
1280
        // Repeated update with the same, unchanged struct
1281
        $secondUpdatedLocation = $locationService->updateLocation($updatedLocation, $updateStruct);
1282
        /* END: Use Case */
1283
1284
        $this->assertEquals($updatedLocation->priority, 42);
1285
        $this->assertEquals($secondUpdatedLocation->priority, 42);
1286
    }
1287
1288
    /**
1289
     * Test for the swapLocation() method.
1290
     *
1291
     * @see \eZ\Publish\API\Repository\LocationService::swapLocation()
1292
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1293
     */
1294
    public function testSwapLocation()
1295
    {
1296
        $repository = $this->getRepository();
1297
        $locationService = $repository->getLocationService();
1298
1299
        $mediaLocationId = $this->generateId('location', 43);
1300
        $demoDesignLocationId = $this->generateId('location', 56);
1301
1302
        $mediaContentInfo = $locationService->loadLocation($mediaLocationId)->getContentInfo();
1303
        $demoDesignContentInfo = $locationService->loadLocation($demoDesignLocationId)->getContentInfo();
1304
1305
        /* BEGIN: Use Case */
1306
        // $mediaLocationId is the ID of the "Media" page location in
1307
        // an eZ Publish demo installation
1308
1309
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1310
        // Publish demo installation
1311
1312
        // Load the location service
1313
        $locationService = $repository->getLocationService();
1314
1315
        $mediaLocation = $locationService->loadLocation($mediaLocationId);
1316
        $demoDesignLocation = $locationService->loadLocation($demoDesignLocationId);
1317
1318
        // Swaps the content referred to by the locations
1319
        $locationService->swapLocation($mediaLocation, $demoDesignLocation);
1320
        /* END: Use Case */
1321
1322
        // Reload Locations, IDs swapped
1323
        $demoDesignLocation = $locationService->loadLocation($mediaLocationId);
1324
        $mediaLocation = $locationService->loadLocation($demoDesignLocationId);
1325
1326
        // Assert Location's Content is updated
1327
        $this->assertEquals(
1328
            $mediaContentInfo->id,
1329
            $mediaLocation->getContentInfo()->id
1330
        );
1331
        $this->assertEquals(
1332
            $demoDesignContentInfo->id,
1333
            $demoDesignLocation->getContentInfo()->id
1334
        );
1335
1336
        // Assert URL aliases are updated
1337
        $this->assertEquals(
1338
            $mediaLocation->id,
1339
            $repository->getURLAliasService()->lookup('/Design/Media')->destination
1340
        );
1341
        $this->assertEquals(
1342
            $demoDesignLocation->id,
1343
            $repository->getURLAliasService()->lookup('/eZ-Publish-Demo-Design-without-demo-content')->destination
1344
        );
1345
    }
1346
1347
    /**
1348
     * Test swapping secondary Location with main Location.
1349
     *
1350
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1351
     *
1352
     * @see https://jira.ez.no/browse/EZP-28663
1353
     *
1354
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1355
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1356
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1357
     *
1358
     * @return int[]
1359
     */
1360
    public function testSwapLocationForMainAndSecondaryLocation(): array
1361
    {
1362
        $repository = $this->getRepository();
1363
        $locationService = $repository->getLocationService();
1364
        $contentService = $repository->getContentService();
1365
1366
        $folder1 = $this->createFolder(['eng-GB' => 'Folder1'], 2);
1367
        $folder2 = $this->createFolder(['eng-GB' => 'Folder2'], 2);
1368
        $folder3 = $this->createFolder(['eng-GB' => 'Folder3'], 2);
1369
1370
        $primaryLocation = $locationService->loadLocation($folder1->contentInfo->mainLocationId);
1371
        $parentLocation = $locationService->loadLocation($folder2->contentInfo->mainLocationId);
1372
        $secondaryLocation = $locationService->createLocation(
1373
            $folder1->contentInfo,
1374
            $locationService->newLocationCreateStruct($parentLocation->id)
1375
        );
1376
1377
        $targetLocation = $locationService->loadLocation($folder3->contentInfo->mainLocationId);
1378
1379
        // perform sanity checks
1380
        $this->assertContentHasExpectedLocations([$primaryLocation, $secondaryLocation], $folder1);
1381
1382
        // begin use case
1383
        $locationService->swapLocation($secondaryLocation, $targetLocation);
1384
1385
        // test results
1386
        $primaryLocation = $locationService->loadLocation($primaryLocation->id);
1387
        $secondaryLocation = $locationService->loadLocation($secondaryLocation->id);
1388
        $targetLocation = $locationService->loadLocation($targetLocation->id);
1389
1390
        self::assertEquals($folder1->id, $primaryLocation->contentInfo->id);
1391
        self::assertEquals($folder1->id, $targetLocation->contentInfo->id);
1392
        self::assertEquals($folder3->id, $secondaryLocation->contentInfo->id);
1393
1394
        $this->assertContentHasExpectedLocations([$primaryLocation, $targetLocation], $folder1);
1395
1396
        self::assertEquals(
1397
            $folder1,
1398
            $contentService->loadContent($folder1->id)
1399
        );
1400
1401
        self::assertEquals(
1402
            $folder2,
1403
            $contentService->loadContent($folder2->id)
1404
        );
1405
1406
        // only in case of Folder 3, main location id changed due to swap
1407
        self::assertEquals(
1408
            $secondaryLocation->id,
1409
            $contentService->loadContent($folder3->id)->contentInfo->mainLocationId
1410
        );
1411
1412
        return [$folder1, $folder2, $folder3];
1413
    }
1414
1415
    /**
1416
     * Compare Ids of expected and loaded Locations for the given Content.
1417
     *
1418
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $expectedLocations
1419
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1420
     *
1421
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
1422
     */
1423
    private function assertContentHasExpectedLocations(array $expectedLocations, Content $content)
1424
    {
1425
        $repository = $this->getRepository(false);
1426
        $locationService = $repository->getLocationService();
1427
1428
        $expectedLocationIds = array_map(
1429
            function (Location $location) {
1430
                return (int)$location->id;
1431
            },
1432
            $expectedLocations
1433
        );
1434
1435
        $actualLocationsIds = array_map(
1436
            function (Location $location) {
1437
                return $location->id;
1438
            },
1439
            $locationService->loadLocations($content->contentInfo)
1440
        );
1441
        self::assertCount(count($expectedLocations), $actualLocationsIds);
1442
1443
        // perform unordered equality assertion
1444
        self::assertEquals(
1445
            $expectedLocationIds,
1446
            $actualLocationsIds,
1447
            sprintf(
1448
                'Content %d contains Locations %s, but expected: %s',
1449
                $content->id,
1450
                implode(', ', $actualLocationsIds),
1451
                implode(', ', $expectedLocationIds)
1452
            ),
1453
            0.0,
1454
            10,
1455
            true
1456
        );
1457
    }
1458
1459
    /**
1460
     * @depends testSwapLocationForMainAndSecondaryLocation
1461
     *
1462
     * @param \eZ\Publish\API\Repository\Values\Content\Content[] $contentItems Content items created by testSwapLocationForSecondaryLocation
1463
     *
1464
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1465
     */
1466
    public function testSwapLocationDoesNotCorruptSearchResults(array $contentItems)
1467
    {
1468
        $repository = $this->getRepository(false);
1469
        $searchService = $repository->getSearchService();
1470
1471
        $this->refreshSearch($repository);
1472
1473
        $contentIds = array_map(
1474
            function (Content $content) {
1475
                return $content->id;
1476
            },
1477
            $contentItems
1478
        );
1479
1480
        $query = new Query();
1481
        $query->filter = new Query\Criterion\ContentId($contentIds);
1482
1483
        $searchResult = $searchService->findContent($query);
1484
1485
        self::assertEquals(count($contentItems), $searchResult->totalCount);
1486
        self::assertEquals(
1487
            $searchResult->totalCount,
1488
            count($searchResult->searchHits),
1489
            'Total count of search result hits does not match the actual number of found results'
1490
        );
1491
        $foundContentIds = array_map(
1492
            function (SearchHit $searchHit) {
1493
                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...
1494
            },
1495
            $searchResult->searchHits
1496
        );
1497
        sort($contentIds);
1498
        sort($foundContentIds);
1499
        self::assertSame(
1500
            $contentIds,
1501
            $foundContentIds,
1502
            'Got different than expected Content item Ids'
1503
        );
1504
    }
1505
1506
    /**
1507
     * Test swapping two secondary (non-main) Locations.
1508
     *
1509
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1510
     *
1511
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1512
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1513
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1514
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1515
     */
1516
    public function testSwapLocationForSecondaryLocations()
1517
    {
1518
        $repository = $this->getRepository();
1519
        $locationService = $repository->getLocationService();
1520
        $contentService = $repository->getContentService();
1521
1522
        $folder1 = $this->createFolder(['eng-GB' => 'Folder1'], 2);
1523
        $folder2 = $this->createFolder(['eng-GB' => 'Folder2'], 2);
1524
        $parentFolder1 = $this->createFolder(['eng-GB' => 'Parent1'], 2);
1525
        $parentFolder2 = $this->createFolder(['eng-GB' => 'Parent2'], 2);
1526
1527
        $parentLocation1 = $locationService->loadLocation($parentFolder1->contentInfo->mainLocationId);
1528
        $parentLocation2 = $locationService->loadLocation($parentFolder2->contentInfo->mainLocationId);
1529
        $secondaryLocation1 = $locationService->createLocation(
1530
            $folder1->contentInfo,
1531
            $locationService->newLocationCreateStruct($parentLocation1->id)
1532
        );
1533
        $secondaryLocation2 = $locationService->createLocation(
1534
            $folder2->contentInfo,
1535
            $locationService->newLocationCreateStruct($parentLocation2->id)
1536
        );
1537
1538
        // begin use case
1539
        $locationService->swapLocation($secondaryLocation1, $secondaryLocation2);
1540
1541
        // test results
1542
        $secondaryLocation1 = $locationService->loadLocation($secondaryLocation1->id);
1543
        $secondaryLocation2 = $locationService->loadLocation($secondaryLocation2->id);
1544
1545
        self::assertEquals($folder2->id, $secondaryLocation1->contentInfo->id);
1546
        self::assertEquals($folder1->id, $secondaryLocation2->contentInfo->id);
1547
1548
        self::assertEquals(
1549
            $folder1,
1550
            $contentService->loadContent($folder1->id)
1551
        );
1552
1553
        self::assertEquals(
1554
            $folder2,
1555
            $contentService->loadContent($folder2->id)
1556
        );
1557
    }
1558
1559
    /**
1560
     * Test swapping Main Location of a Content with another one updates Content item Main Location.
1561
     *
1562
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1563
     */
1564
    public function testSwapLocationUpdatesMainLocation()
1565
    {
1566
        $repository = $this->getRepository();
1567
        $locationService = $repository->getLocationService();
1568
        $contentService = $repository->getContentService();
1569
1570
        $mainLocationParentId = 60;
1571
        $secondaryLocationId = 43;
1572
1573
        $publishedContent = $this->publishContentWithParentLocation(
1574
            'Content for Swap Location Test', $mainLocationParentId
1575
        );
1576
1577
        // sanity check
1578
        $mainLocation = $locationService->loadLocation($publishedContent->contentInfo->mainLocationId);
1579
        self::assertEquals($mainLocationParentId, $mainLocation->parentLocationId);
1580
1581
        // load another pre-existing location
1582
        $secondaryLocation = $locationService->loadLocation($secondaryLocationId);
1583
1584
        // swap the Main Location with a secondary one
1585
        $locationService->swapLocation($mainLocation, $secondaryLocation);
1586
1587
        // check if Main Location has been updated
1588
        $mainLocation = $locationService->loadLocation($secondaryLocation->id);
1589
        self::assertEquals($publishedContent->contentInfo->id, $mainLocation->contentInfo->id);
1590
        self::assertEquals($mainLocation->id, $mainLocation->contentInfo->mainLocationId);
1591
1592
        $reloadedContent = $contentService->loadContentByContentInfo($publishedContent->contentInfo);
1593
        self::assertEquals($mainLocation->id, $reloadedContent->contentInfo->mainLocationId);
1594
    }
1595
1596
    /**
1597
     * Test if location swap affects related bookmarks.
1598
     *
1599
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1600
     */
1601
    public function testBookmarksAreSwappedAfterSwapLocation()
1602
    {
1603
        $repository = $this->getRepository();
1604
1605
        $mediaLocationId = $this->generateId('location', 43);
1606
        $demoDesignLocationId = $this->generateId('location', 56);
1607
1608
        /* BEGIN: Use Case */
1609
        $locationService = $repository->getLocationService();
1610
        $bookmarkService = $repository->getBookmarkService();
1611
1612
        $mediaLocation = $locationService->loadLocation($mediaLocationId);
1613
        $demoDesignLocation = $locationService->loadLocation($demoDesignLocationId);
1614
1615
        // Bookmark locations
1616
        $bookmarkService->createBookmark($mediaLocation);
1617
        $bookmarkService->createBookmark($demoDesignLocation);
1618
1619
        $beforeSwap = $bookmarkService->loadBookmarks();
1620
1621
        // Swaps the content referred to by the locations
1622
        $locationService->swapLocation($mediaLocation, $demoDesignLocation);
1623
1624
        $afterSwap = $bookmarkService->loadBookmarks();
1625
        /* END: Use Case */
1626
1627
        $this->assertEquals($beforeSwap->items[0]->id, $afterSwap->items[1]->id);
1628
        $this->assertEquals($beforeSwap->items[1]->id, $afterSwap->items[0]->id);
1629
    }
1630
1631
    /**
1632
     * Test for the hideLocation() method.
1633
     *
1634
     * @see \eZ\Publish\API\Repository\LocationService::hideLocation()
1635
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1636
     */
1637
    public function testHideLocation()
1638
    {
1639
        $repository = $this->getRepository();
1640
1641
        $locationId = $this->generateId('location', 5);
1642
        /* BEGIN: Use Case */
1643
        // $locationId is the ID of an existing location
1644
        $locationService = $repository->getLocationService();
1645
1646
        $visibleLocation = $locationService->loadLocation($locationId);
1647
1648
        $hiddenLocation = $locationService->hideLocation($visibleLocation);
1649
        /* END: Use Case */
1650
1651
        $this->assertInstanceOf(
1652
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1653
            $hiddenLocation
1654
        );
1655
1656
        $this->assertTrue(
1657
            $hiddenLocation->hidden,
1658
            sprintf(
1659
                'Location with ID "%s" not hidden.',
1660
                $hiddenLocation->id
1661
            )
1662
        );
1663
1664
        $this->refreshSearch($repository);
1665
1666
        foreach ($locationService->loadLocationChildren($hiddenLocation)->locations as $child) {
1667
            $this->assertSubtreeProperties(
1668
                array('invisible' => true),
1669
                $child
1670
            );
1671
        }
1672
    }
1673
1674
    /**
1675
     * Assert that $expectedValues are set in the subtree starting at $location.
1676
     *
1677
     * @param array $expectedValues
1678
     * @param Location $location
1679
     */
1680
    protected function assertSubtreeProperties(array $expectedValues, Location $location, $stopId = null)
1681
    {
1682
        $repository = $this->getRepository();
1683
        $locationService = $repository->getLocationService();
1684
1685
        if ($location->id === $stopId) {
1686
            return;
1687
        }
1688
1689
        foreach ($expectedValues as $propertyName => $propertyValue) {
1690
            $this->assertEquals(
1691
                $propertyValue,
1692
                $location->$propertyName
1693
            );
1694
1695
            foreach ($locationService->loadLocationChildren($location)->locations as $child) {
1696
                $this->assertSubtreeProperties($expectedValues, $child);
1697
            }
1698
        }
1699
    }
1700
1701
    /**
1702
     * Test for the unhideLocation() method.
1703
     *
1704
     * @see \eZ\Publish\API\Repository\LocationService::unhideLocation()
1705
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testHideLocation
1706
     */
1707
    public function testUnhideLocation()
1708
    {
1709
        $repository = $this->getRepository();
1710
1711
        $locationId = $this->generateId('location', 5);
1712
        /* BEGIN: Use Case */
1713
        // $locationId is the ID of an existing location
1714
        $locationService = $repository->getLocationService();
1715
1716
        $visibleLocation = $locationService->loadLocation($locationId);
1717
        $hiddenLocation = $locationService->hideLocation($visibleLocation);
1718
1719
        $unHiddenLocation = $locationService->unhideLocation($hiddenLocation);
1720
        /* END: Use Case */
1721
1722
        $this->assertInstanceOf(
1723
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1724
            $unHiddenLocation
1725
        );
1726
1727
        $this->assertFalse(
1728
            $unHiddenLocation->hidden,
1729
            sprintf(
1730
                'Location with ID "%s" not unhidden.',
1731
                $unHiddenLocation->id
1732
            )
1733
        );
1734
1735
        $this->refreshSearch($repository);
1736
1737
        foreach ($locationService->loadLocationChildren($unHiddenLocation)->locations as $child) {
1738
            $this->assertSubtreeProperties(
1739
                array('invisible' => false),
1740
                $child
1741
            );
1742
        }
1743
    }
1744
1745
    /**
1746
     * Test for the unhideLocation() method.
1747
     *
1748
     * @see \eZ\Publish\API\Repository\LocationService::unhideLocation()
1749
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testUnhideLocation
1750
     */
1751
    public function testUnhideLocationNotUnhidesHiddenSubtree()
1752
    {
1753
        $repository = $this->getRepository();
1754
1755
        $higherLocationId = $this->generateId('location', 5);
1756
        $lowerLocationId = $this->generateId('location', 13);
1757
        /* BEGIN: Use Case */
1758
        // $higherLocationId is the ID of a location
1759
        // $lowerLocationId is the ID of a location below $higherLocationId
1760
        $locationService = $repository->getLocationService();
1761
1762
        $higherLocation = $locationService->loadLocation($higherLocationId);
1763
        $hiddenHigherLocation = $locationService->hideLocation($higherLocation);
1764
1765
        $lowerLocation = $locationService->loadLocation($lowerLocationId);
1766
        $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...
1767
1768
        $unHiddenHigherLocation = $locationService->unhideLocation($hiddenHigherLocation);
1769
        /* END: Use Case */
1770
1771
        $this->assertInstanceOf(
1772
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1773
            $unHiddenHigherLocation
1774
        );
1775
1776
        $this->assertFalse(
1777
            $unHiddenHigherLocation->hidden,
1778
            sprintf(
1779
                'Location with ID "%s" not unhidden.',
1780
                $unHiddenHigherLocation->id
1781
            )
1782
        );
1783
1784
        $this->refreshSearch($repository);
1785
1786
        foreach ($locationService->loadLocationChildren($unHiddenHigherLocation)->locations as $child) {
1787
            $this->assertSubtreeProperties(
1788
                array('invisible' => false),
1789
                $child,
1790
                $this->generateId('location', 13)
1791
            );
1792
        }
1793
1794
        $stillHiddenLocation = $locationService->loadLocation($this->generateId('location', 13));
1795
        $this->assertTrue(
1796
            $stillHiddenLocation->hidden,
1797
            sprintf(
1798
                'Hidden sub-location with ID %s accidentally unhidden.',
1799
                $stillHiddenLocation->id
1800
            )
1801
        );
1802
        foreach ($locationService->loadLocationChildren($stillHiddenLocation)->locations as $child) {
1803
            $this->assertSubtreeProperties(
1804
                array('invisible' => true),
1805
                $child
1806
            );
1807
        }
1808
    }
1809
1810
    /**
1811
     * Test for the deleteLocation() method.
1812
     *
1813
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1814
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1815
     */
1816
    public function testDeleteLocation()
1817
    {
1818
        $repository = $this->getRepository();
1819
1820
        $mediaLocationId = $this->generateId('location', 43);
1821
        /* BEGIN: Use Case */
1822
        // $mediaLocationId is the ID of the location of the
1823
        // "Media" location in an eZ Publish demo installation
1824
        $locationService = $repository->getLocationService();
1825
1826
        $location = $locationService->loadLocation($mediaLocationId);
1827
1828
        $locationService->deleteLocation($location);
1829
        /* END: Use Case */
1830
1831
        try {
1832
            $locationService->loadLocation($mediaLocationId);
1833
            $this->fail("Location $mediaLocationId not deleted.");
1834
        } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1835
        }
1836
1837
        // The following IDs are IDs of child locations of $mediaLocationId location
1838
        // ( Media/Images, Media/Files, Media/Multimedia respectively )
1839
        foreach (array(51, 52, 53) as $childLocationId) {
1840
            try {
1841
                $locationService->loadLocation($this->generateId('location', $childLocationId));
1842
                $this->fail("Location $childLocationId not deleted.");
1843
            } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1844
            }
1845
        }
1846
1847
        // The following IDs are IDs of content below $mediaLocationId location
1848
        // ( Media/Images, Media/Files, Media/Multimedia respectively )
1849
        $contentService = $this->getRepository()->getContentService();
1850
        foreach (array(49, 50, 51) as $childContentId) {
1851
            try {
1852
                $contentService->loadContentInfo($this->generateId('object', $childContentId));
1853
                $this->fail("Content $childContentId not deleted.");
1854
            } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1855
            }
1856
        }
1857
    }
1858
1859
    /**
1860
     * Test for the deleteLocation() method.
1861
     *
1862
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1863
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testDeleteLocation
1864
     */
1865
    public function testDeleteLocationDecrementsChildCountOnParent()
1866
    {
1867
        $repository = $this->getRepository();
1868
1869
        $mediaLocationId = $this->generateId('location', 43);
1870
        /* BEGIN: Use Case */
1871
        // $mediaLocationId is the ID of the location of the
1872
        // "Media" location in an eZ Publish demo installation
1873
1874
        $locationService = $repository->getLocationService();
1875
1876
        // Load the current the user group location
1877
        $location = $locationService->loadLocation($mediaLocationId);
1878
1879
        // Load the parent location
1880
        $parentLocation = $locationService->loadLocation(
1881
            $location->parentLocationId
1882
        );
1883
1884
        // Get child count
1885
        $childCountBefore = $locationService->getLocationChildCount($parentLocation);
1886
1887
        // Delete the user group location
1888
        $locationService->deleteLocation($location);
1889
1890
        $this->refreshSearch($repository);
1891
1892
        // Reload parent location
1893
        $parentLocation = $locationService->loadLocation(
1894
            $location->parentLocationId
1895
        );
1896
1897
        // This will be $childCountBefore - 1
1898
        $childCountAfter = $locationService->getLocationChildCount($parentLocation);
1899
        /* END: Use Case */
1900
1901
        $this->assertEquals($childCountBefore - 1, $childCountAfter);
1902
    }
1903
1904
    /**
1905
     * Test for the deleteLocation() method.
1906
     *
1907
     * Related issue: EZP-21904
1908
     *
1909
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1910
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1911
     */
1912
    public function testDeleteContentObjectLastLocation()
1913
    {
1914
        $repository = $this->getRepository();
1915
1916
        /* BEGIN: Use case */
1917
        $contentService = $repository->getContentService();
1918
        $locationService = $repository->getLocationService();
1919
        $contentTypeService = $repository->getContentTypeService();
1920
        $urlAliasService = $repository->getURLAliasService();
1921
1922
        // prepare Content object
1923
        $createStruct = $contentService->newContentCreateStruct(
1924
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1925
            'eng-GB'
1926
        );
1927
        $createStruct->setField('name', 'Test folder');
1928
1929
        // creata Content object
1930
        $content = $contentService->publishVersion(
1931
            $contentService->createContent(
1932
                $createStruct,
1933
                array($locationService->newLocationCreateStruct(2))
1934
            )->versionInfo
1935
        );
1936
1937
        // delete location
1938
        $locationService->deleteLocation(
1939
            $locationService->loadLocation(
1940
                $urlAliasService->lookup('/Test-folder')->destination
1941
            )
1942
        );
1943
1944
        // this should throw a not found exception
1945
        $contentService->loadContent($content->versionInfo->contentInfo->id);
1946
        /* END: Use case*/
1947
    }
1948
1949
    /**
1950
     * Test for the deleteLocation() method.
1951
     *
1952
     * @covers  \eZ\Publish\API\Repository\LocationService::deleteLocation()
1953
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testDeleteLocation
1954
     */
1955
    public function testDeleteLocationDeletesRelatedBookmarks()
1956
    {
1957
        $repository = $this->getRepository();
1958
1959
        $parentLocationId = $this->generateId('location', 43);
1960
        $childLocationId = $this->generateId('location', 53);
1961
1962
        /* BEGIN: Use Case */
1963
        $locationService = $repository->getLocationService();
1964
        $bookmarkService = $repository->getBookmarkService();
1965
1966
        // Load location
1967
        $childLocation = $locationService->loadLocation($childLocationId);
1968
        // Add location to bookmarks
1969
        $bookmarkService->createBookmark($childLocation);
1970
        // Load parent location
1971
        $parentLocation = $locationService->loadLocation($parentLocationId);
1972
        // Delete parent location
1973
        $locationService->deleteLocation($parentLocation);
1974
        /* END: Use Case */
1975
1976
        // Location isn't bookmarked anymore
1977
        foreach ($bookmarkService->loadBookmarks(0, 9999) as $bookmarkedLocation) {
1978
            $this->assertNotEquals($childLocation->id, $bookmarkedLocation->id);
1979
        }
1980
    }
1981
1982
    /**
1983
     * Test for the copySubtree() method.
1984
     *
1985
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1986
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1987
     */
1988
    public function testCopySubtree()
1989
    {
1990
        $repository = $this->getRepository();
1991
1992
        $mediaLocationId = $this->generateId('location', 43);
1993
        $demoDesignLocationId = $this->generateId('location', 56);
1994
        /* BEGIN: Use Case */
1995
        // $mediaLocationId is the ID of the "Media" page location in
1996
        // an eZ Publish demo installation
1997
1998
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1999
        // Publish demo installation
2000
2001
        // Load the location service
2002
        $locationService = $repository->getLocationService();
2003
2004
        // Load location to copy
2005
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
2006
2007
        // Load new parent location
2008
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2009
2010
        // Copy location "Media" to "Demo Design"
2011
        $copiedLocation = $locationService->copySubtree(
2012
            $locationToCopy,
2013
            $newParentLocation
2014
        );
2015
        /* END: Use Case */
2016
2017
        $this->assertInstanceOf(
2018
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
2019
            $copiedLocation
2020
        );
2021
2022
        $this->assertPropertiesCorrect(
2023
            array(
2024
                'depth' => $newParentLocation->depth + 1,
2025
                'parentLocationId' => $newParentLocation->id,
2026
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $copiedLocation->id) . '/',
2027
            ),
2028
            $copiedLocation
2029
        );
2030
2031
        $this->assertDefaultContentStates($copiedLocation->contentInfo);
2032
    }
2033
2034
    /**
2035
     * Test for the copySubtree() method.
2036
     *
2037
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
2038
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
2039
     */
2040
    public function testCopySubtreeWithAliases()
2041
    {
2042
        $repository = $this->getRepository();
2043
        $urlAliasService = $repository->getURLAliasService();
2044
2045
        // $mediaLocationId is the ID of the "Media" page location in
2046
        // an eZ Publish demo installation
2047
2048
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2049
        // Publish demo installation
2050
        $mediaLocationId = $this->generateId('location', 43);
2051
        $demoDesignLocationId = $this->generateId('location', 56);
2052
2053
        $locationService = $repository->getLocationService();
2054
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
2055
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2056
2057
        $expectedSubItemAliases = [
2058
            '/Design/Plain-site/Media/Multimedia',
2059
            '/Design/Plain-site/Media/Images',
2060
            '/Design/Plain-site/Media/Files',
2061
        ];
2062
2063
        $this->assertAliasesBeforeCopy($urlAliasService, $expectedSubItemAliases);
2064
2065
        // Copy location "Media" to "Design"
2066
        $locationService->copySubtree(
2067
            $locationToCopy,
2068
            $newParentLocation
2069
        );
2070
2071
        $this->assertGeneratedAliases($urlAliasService, $expectedSubItemAliases);
2072
    }
2073
2074
    /**
2075
     * Asserts that given Content has default ContentStates.
2076
     *
2077
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
2078
     */
2079 View Code Duplication
    private function assertDefaultContentStates(ContentInfo $contentInfo)
2080
    {
2081
        $repository = $this->getRepository();
2082
        $objectStateService = $repository->getObjectStateService();
2083
2084
        $objectStateGroups = $objectStateService->loadObjectStateGroups();
2085
2086
        foreach ($objectStateGroups as $objectStateGroup) {
2087
            $contentState = $objectStateService->getContentState($contentInfo, $objectStateGroup);
2088
            foreach ($objectStateService->loadObjectStates($objectStateGroup) as $objectState) {
2089
                // Only check the first object state which is the default one.
2090
                $this->assertEquals(
2091
                    $objectState,
2092
                    $contentState
2093
                );
2094
                break;
2095
            }
2096
        }
2097
    }
2098
2099
    /**
2100
     * Test for the copySubtree() method.
2101
     *
2102
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
2103
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
2104
     */
2105
    public function testCopySubtreeUpdatesSubtreeProperties()
2106
    {
2107
        $repository = $this->getRepository();
2108
        $locationService = $repository->getLocationService();
2109
2110
        $locationToCopy = $locationService->loadLocation($this->generateId('location', 43));
2111
2112
        // Load Subtree properties before copy
2113
        $expected = $this->loadSubtreeProperties($locationToCopy);
2114
2115
        $mediaLocationId = $this->generateId('location', 43);
2116
        $demoDesignLocationId = $this->generateId('location', 56);
2117
        /* BEGIN: Use Case */
2118
        // $mediaLocationId is the ID of the "Media" page location in
2119
        // an eZ Publish demo installation
2120
2121
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2122
        // Publish demo installation
2123
2124
        // Load the location service
2125
        $locationService = $repository->getLocationService();
2126
2127
        // Load location to copy
2128
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
2129
2130
        // Load new parent location
2131
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2132
2133
        // Copy location "Media" to "Demo Design"
2134
        $copiedLocation = $locationService->copySubtree(
2135
            $locationToCopy,
2136
            $newParentLocation
2137
        );
2138
        /* END: Use Case */
2139
2140
        $beforeIds = array();
2141
        foreach ($expected as $properties) {
2142
            $beforeIds[] = $properties['id'];
2143
        }
2144
2145
        $this->refreshSearch($repository);
2146
2147
        // Load Subtree properties after copy
2148
        $actual = $this->loadSubtreeProperties($copiedLocation);
2149
2150
        $this->assertEquals(count($expected), count($actual));
2151
2152
        foreach ($actual as $properties) {
2153
            $this->assertNotContains($properties['id'], $beforeIds);
2154
            $this->assertStringStartsWith(
2155
                $newParentLocation->pathString . $this->parseId('location', $copiedLocation->id) . '/',
2156
                $properties['pathString']
2157
            );
2158
            $this->assertStringEndsWith(
2159
                '/' . $this->parseId('location', $properties['id']) . '/',
2160
                $properties['pathString']
2161
            );
2162
        }
2163
    }
2164
2165
    /**
2166
     * Test for the copySubtree() method.
2167
     *
2168
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
2169
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
2170
     */
2171
    public function testCopySubtreeIncrementsChildCountOfNewParent()
2172
    {
2173
        $repository = $this->getRepository();
2174
        $locationService = $repository->getLocationService();
2175
2176
        $childCountBefore = $locationService->getLocationChildCount($locationService->loadLocation(56));
2177
2178
        $mediaLocationId = $this->generateId('location', 43);
2179
        $demoDesignLocationId = $this->generateId('location', 56);
2180
        /* BEGIN: Use Case */
2181
        // $mediaLocationId is the ID of the "Media" page location in
2182
        // an eZ Publish demo installation
2183
2184
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2185
        // Publish demo installation
2186
2187
        // Load the location service
2188
        $locationService = $repository->getLocationService();
2189
2190
        // Load location to copy
2191
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
2192
2193
        // Load new parent location
2194
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2195
2196
        // Copy location "Media" to "Demo Design"
2197
        $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...
2198
            $locationToCopy,
2199
            $newParentLocation
2200
        );
2201
        /* END: Use Case */
2202
2203
        $this->refreshSearch($repository);
2204
2205
        $childCountAfter = $locationService->getLocationChildCount($locationService->loadLocation($demoDesignLocationId));
2206
2207
        $this->assertEquals($childCountBefore + 1, $childCountAfter);
2208
    }
2209
2210
    /**
2211
     * Test for the copySubtree() method.
2212
     *
2213
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
2214
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2215
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
2216
     */
2217 View Code Duplication
    public function testCopySubtreeThrowsInvalidArgumentException()
2218
    {
2219
        $repository = $this->getRepository();
2220
2221
        $communityLocationId = $this->generateId('location', 5);
2222
        /* BEGIN: Use Case */
2223
        // $communityLocationId is the ID of the "Community" page location in
2224
        // an eZ Publish demo installation
2225
2226
        // Load the location service
2227
        $locationService = $repository->getLocationService();
2228
2229
        // Load location to copy
2230
        $locationToCopy = $locationService->loadLocation($communityLocationId);
2231
2232
        // Use a child as new parent
2233
        $childLocations = $locationService->loadLocationChildren($locationToCopy)->locations;
2234
        $newParentLocation = end($childLocations);
2235
2236
        // This call will fail with an "InvalidArgumentException", because the
2237
        // new parent is a child location of the subtree to copy.
2238
        $locationService->copySubtree(
2239
            $locationToCopy,
2240
            $newParentLocation
0 ignored issues
show
Security Bug introduced by
It seems like $newParentLocation defined by end($childLocations) on line 2234 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...
2241
        );
2242
        /* END: Use Case */
2243
    }
2244
2245
    /**
2246
     * Test for the moveSubtree() method.
2247
     *
2248
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2249
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
2250
     */
2251
    public function testMoveSubtree()
2252
    {
2253
        $repository = $this->getRepository();
2254
2255
        $mediaLocationId = $this->generateId('location', 43);
2256
        $demoDesignLocationId = $this->generateId('location', 56);
2257
        /* BEGIN: Use Case */
2258
        // $mediaLocationId is the ID of the "Media" page location in
2259
        // an eZ Publish demo installation
2260
2261
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2262
        // Publish demo installation
2263
2264
        // Load the location service
2265
        $locationService = $repository->getLocationService();
2266
2267
        // Load location to move
2268
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2269
2270
        // Load new parent location
2271
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2272
2273
        // Move location from "Home" to "Demo Design"
2274
        $locationService->moveSubtree(
2275
            $locationToMove,
2276
            $newParentLocation
2277
        );
2278
2279
        // Load moved location
2280
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2281
        /* END: Use Case */
2282
2283
        $this->assertPropertiesCorrect(
2284
            array(
2285
                'hidden' => false,
2286
                'invisible' => false,
2287
                'depth' => $newParentLocation->depth + 1,
2288
                'parentLocationId' => $newParentLocation->id,
2289
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $movedLocation->id) . '/',
2290
            ),
2291
            $movedLocation
2292
        );
2293
    }
2294
2295
    /**
2296
     * Test for the moveSubtree() method.
2297
     *
2298
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2299
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2300
     */
2301
    public function testMoveSubtreeHidden()
2302
    {
2303
        $repository = $this->getRepository();
2304
2305
        $mediaLocationId = $this->generateId('location', 43);
2306
        $demoDesignLocationId = $this->generateId('location', 56);
2307
        /* BEGIN: Use Case */
2308
        // $mediaLocationId is the ID of the "Media" page location in
2309
        // an eZ Publish demo installation
2310
2311
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2312
        // Publish demo installation
2313
2314
        // Load the location service
2315
        $locationService = $repository->getLocationService();
2316
2317
        // Load location to move
2318
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2319
2320
        // Load new parent location
2321
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2322
2323
        // Hide the target location before we move
2324
        $newParentLocation = $locationService->hideLocation($newParentLocation);
2325
2326
        // Move location from "Home" to "Demo Design"
2327
        $locationService->moveSubtree(
2328
            $locationToMove,
2329
            $newParentLocation
2330
        );
2331
2332
        // Load moved location
2333
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2334
        /* END: Use Case */
2335
2336
        $this->assertPropertiesCorrect(
2337
            array(
2338
                'hidden' => false,
2339
                'invisible' => true,
2340
                'depth' => $newParentLocation->depth + 1,
2341
                'parentLocationId' => $newParentLocation->id,
2342
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $movedLocation->id) . '/',
2343
            ),
2344
            $movedLocation
2345
        );
2346
    }
2347
2348
    /**
2349
     * Test for the moveSubtree() method.
2350
     *
2351
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2352
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2353
     */
2354
    public function testMoveSubtreeUpdatesSubtreeProperties()
2355
    {
2356
        $repository = $this->getRepository();
2357
        $locationService = $repository->getLocationService();
2358
2359
        $locationToMove = $locationService->loadLocation($this->generateId('location', 43));
2360
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2361
2362
        // Load Subtree properties before move
2363
        $expected = $this->loadSubtreeProperties($locationToMove);
2364
        foreach ($expected as $id => $properties) {
2365
            $expected[$id]['depth'] = $properties['depth'] + 2;
2366
            $expected[$id]['pathString'] = str_replace(
2367
                $locationToMove->pathString,
2368
                $newParentLocation->pathString . $this->parseId('location', $locationToMove->id) . '/',
2369
                $properties['pathString']
2370
            );
2371
        }
2372
2373
        $mediaLocationId = $this->generateId('location', 43);
2374
        $demoDesignLocationId = $this->generateId('location', 56);
2375
        /* BEGIN: Use Case */
2376
        // $mediaLocationId is the ID of the "Media" page location in
2377
        // an eZ Publish demo installation
2378
2379
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2380
        // Publish demo installation
2381
2382
        // Load the location service
2383
        $locationService = $repository->getLocationService();
2384
2385
        // Load location to move
2386
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2387
2388
        // Load new parent location
2389
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2390
2391
        // Move location from "Home" to "Demo Design"
2392
        $locationService->moveSubtree(
2393
            $locationToMove,
2394
            $newParentLocation
2395
        );
2396
2397
        // Load moved location
2398
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2399
        /* END: Use Case */
2400
2401
        $this->refreshSearch($repository);
2402
2403
        // Load Subtree properties after move
2404
        $actual = $this->loadSubtreeProperties($movedLocation);
2405
2406
        $this->assertEquals($expected, $actual);
2407
    }
2408
2409
    /**
2410
     * Test for the moveSubtree() method.
2411
     *
2412
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2413
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtreeUpdatesSubtreeProperties
2414
     */
2415
    public function testMoveSubtreeUpdatesSubtreePropertiesHidden()
2416
    {
2417
        $repository = $this->getRepository();
2418
        $locationService = $repository->getLocationService();
2419
2420
        $locationToMove = $locationService->loadLocation($this->generateId('location', 43));
2421
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2422
2423
        // Hide the target location before we move
2424
        $newParentLocation = $locationService->hideLocation($newParentLocation);
2425
2426
        // Load Subtree properties before move
2427
        $expected = $this->loadSubtreeProperties($locationToMove);
2428
        foreach ($expected as $id => $properties) {
2429
            $expected[$id]['invisible'] = true;
2430
            $expected[$id]['depth'] = $properties['depth'] + 2;
2431
            $expected[$id]['pathString'] = str_replace(
2432
                $locationToMove->pathString,
2433
                $newParentLocation->pathString . $this->parseId('location', $locationToMove->id) . '/',
2434
                $properties['pathString']
2435
            );
2436
        }
2437
2438
        $mediaLocationId = $this->generateId('location', 43);
2439
        $demoDesignLocationId = $this->generateId('location', 56);
2440
        /* BEGIN: Use Case */
2441
        // $mediaLocationId is the ID of the "Media" page location in
2442
        // an eZ Publish demo installation
2443
2444
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2445
        // Publish demo installation
2446
2447
        // Load the location service
2448
        $locationService = $repository->getLocationService();
2449
2450
        // Load location to move
2451
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2452
2453
        // Load new parent location
2454
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2455
2456
        // Move location from "Home" to "Demo Design"
2457
        $locationService->moveSubtree(
2458
            $locationToMove,
2459
            $newParentLocation
2460
        );
2461
2462
        // Load moved location
2463
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2464
        /* END: Use Case */
2465
2466
        $this->refreshSearch($repository);
2467
2468
        // Load Subtree properties after move
2469
        $actual = $this->loadSubtreeProperties($movedLocation);
2470
2471
        $this->assertEquals($expected, $actual);
2472
    }
2473
2474
    /**
2475
     * Test for the moveSubtree() method.
2476
     *
2477
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2478
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2479
     */
2480 View Code Duplication
    public function testMoveSubtreeIncrementsChildCountOfNewParent()
2481
    {
2482
        $repository = $this->getRepository();
2483
        $locationService = $repository->getLocationService();
2484
2485
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2486
2487
        // Load expected properties before move
2488
        $expected = $this->loadLocationProperties($newParentLocation);
2489
        $childCountBefore = $locationService->getLocationChildCount($newParentLocation);
2490
2491
        $mediaLocationId = $this->generateId('location', 43);
2492
        $demoDesignLocationId = $this->generateId('location', 56);
2493
        /* BEGIN: Use Case */
2494
        // $mediaLocationId is the ID of the "Media" page location in
2495
        // an eZ Publish demo installation
2496
2497
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2498
        // Publish demo installation
2499
2500
        // Load the location service
2501
        $locationService = $repository->getLocationService();
2502
2503
        // Load location to move
2504
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2505
2506
        // Load new parent location
2507
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2508
2509
        // Move location from "Home" to "Demo Design"
2510
        $locationService->moveSubtree(
2511
            $locationToMove,
2512
            $newParentLocation
2513
        );
2514
2515
        // Load moved location
2516
        $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...
2517
2518
        // Reload new parent location
2519
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2520
        /* END: Use Case */
2521
2522
        $this->refreshSearch($repository);
2523
2524
        // Load Subtree properties after move
2525
        $actual = $this->loadLocationProperties($newParentLocation);
2526
        $childCountAfter = $locationService->getLocationChildCount($newParentLocation);
2527
2528
        $this->assertEquals($expected, $actual);
2529
        $this->assertEquals($childCountBefore + 1, $childCountAfter);
2530
    }
2531
2532
    /**
2533
     * Test for the moveSubtree() method.
2534
     *
2535
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2536
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2537
     */
2538 View Code Duplication
    public function testMoveSubtreeDecrementsChildCountOfOldParent()
2539
    {
2540
        $repository = $this->getRepository();
2541
        $locationService = $repository->getLocationService();
2542
2543
        $oldParentLocation = $locationService->loadLocation($this->generateId('location', 1));
2544
2545
        // Load expected properties before move
2546
        $expected = $this->loadLocationProperties($oldParentLocation);
2547
        $childCountBefore = $locationService->getLocationChildCount($oldParentLocation);
2548
2549
        $mediaLocationId = $this->generateId('location', 43);
2550
        $demoDesignLocationId = $this->generateId('location', 56);
2551
        /* BEGIN: Use Case */
2552
        // $mediaLocationId is the ID of the "Media" page location in
2553
        // an eZ Publish demo installation
2554
2555
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2556
        // Publish demo installation
2557
2558
        // Load the location service
2559
        $locationService = $repository->getLocationService();
2560
2561
        // Load location to move
2562
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2563
2564
        // Get the location id of the old parent
2565
        $oldParentLocationId = $locationToMove->parentLocationId;
2566
2567
        // Load new parent location
2568
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2569
2570
        // Move location from "Home" to "Demo Design"
2571
        $locationService->moveSubtree(
2572
            $locationToMove,
2573
            $newParentLocation
2574
        );
2575
2576
        // Reload old parent location
2577
        $oldParentLocation = $locationService->loadLocation($oldParentLocationId);
2578
        /* END: Use Case */
2579
2580
        $this->refreshSearch($repository);
2581
2582
        // Load Subtree properties after move
2583
        $actual = $this->loadLocationProperties($oldParentLocation);
2584
        $childCountAfter = $locationService->getLocationChildCount($oldParentLocation);
2585
2586
        $this->assertEquals($expected, $actual);
2587
        $this->assertEquals($childCountBefore - 1, $childCountAfter);
2588
    }
2589
2590
    /**
2591
     * Test moving invisible (hidden by parent) subtree.
2592
     *
2593
     * @covers \eZ\Publish\API\Repository\LocationService::moveSubtree
2594
     *
2595
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
2596
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
2597
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
2598
     */
2599
    public function testMoveInvisibleSubtree()
2600
    {
2601
        $repository = $this->getRepository();
2602
        $locationService = $repository->getLocationService();
2603
2604
        $rootLocationId = 2;
2605
2606
        $folder = $this->createFolder(['eng-GB' => 'Folder'], $rootLocationId);
2607
        $child = $this->createFolder(['eng-GB' => 'Child'], $folder->contentInfo->mainLocationId);
2608
        $locationService->hideLocation(
2609
            $locationService->loadLocation($folder->contentInfo->mainLocationId)
2610
        );
2611
        // sanity check
2612
        $childLocation = $locationService->loadLocation($child->contentInfo->mainLocationId);
2613
        self::assertFalse($childLocation->hidden);
2614
        self::assertTrue($childLocation->invisible);
2615
        self::assertEquals($folder->contentInfo->mainLocationId, $childLocation->parentLocationId);
2616
2617
        $destination = $this->createFolder(['eng-GB' => 'Destination'], $rootLocationId);
2618
        $destinationLocation = $locationService->loadLocation(
2619
            $destination->contentInfo->mainLocationId
2620
        );
2621
2622
        $locationService->moveSubtree($childLocation, $destinationLocation);
2623
2624
        $childLocation = $locationService->loadLocation($child->contentInfo->mainLocationId);
2625
        // Business logic - Location moved to visible parent becomes visible
2626
        self::assertFalse($childLocation->hidden);
2627
        self::assertFalse($childLocation->invisible);
2628
        self::assertEquals($destinationLocation->id, $childLocation->parentLocationId);
2629
    }
2630
2631
    /**
2632
     * Test for the moveSubtree() method.
2633
     *
2634
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2635
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2636
     */
2637 View Code Duplication
    public function testMoveSubtreeThrowsInvalidArgumentException()
2638
    {
2639
        $repository = $this->getRepository();
2640
        $mediaLocationId = $this->generateId('location', 43);
2641
        $multimediaLocationId = $this->generateId('location', 53);
2642
2643
        /* BEGIN: Use Case */
2644
        // $mediaLocationId is the ID of the "Media" page location in
2645
        // an eZ Publish demo installation
2646
2647
        // $multimediaLocationId is the ID of the "Multimedia" page location in an eZ
2648
        // Publish demo installation
2649
2650
        // Load the location service
2651
        $locationService = $repository->getLocationService();
2652
2653
        // Load location to move
2654
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2655
2656
        // Load new parent location
2657
        $newParentLocation = $locationService->loadLocation($multimediaLocationId);
2658
2659
        // Throws an exception because new parent location is placed below location to move
2660
        $locationService->moveSubtree(
2661
            $locationToMove,
2662
            $newParentLocation
2663
        );
2664
        /* END: Use Case */
2665
    }
2666
2667
    /**
2668
     * Loads properties from all locations in the $location's subtree.
2669
     *
2670
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
2671
     * @param array $properties
2672
     *
2673
     * @return array
2674
     */
2675
    private function loadSubtreeProperties(Location $location, array $properties = array())
2676
    {
2677
        $locationService = $this->getRepository()->getLocationService();
2678
2679
        foreach ($locationService->loadLocationChildren($location)->locations as $childLocation) {
2680
            $properties[] = $this->loadLocationProperties($childLocation);
2681
2682
            $properties = $this->loadSubtreeProperties($childLocation, $properties);
2683
        }
2684
2685
        return $properties;
2686
    }
2687
2688
    /**
2689
     * Loads assertable properties from the given location.
2690
     *
2691
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
2692
     * @param mixed[] $overwrite
2693
     *
2694
     * @return array
2695
     */
2696 View Code Duplication
    private function loadLocationProperties(Location $location, array $overwrite = array())
2697
    {
2698
        return array_merge(
2699
            array(
2700
                'id' => $location->id,
2701
                'depth' => $location->depth,
2702
                'parentLocationId' => $location->parentLocationId,
2703
                'pathString' => $location->pathString,
2704
                'remoteId' => $location->remoteId,
2705
                'hidden' => $location->hidden,
2706
                'invisible' => $location->invisible,
2707
                'priority' => $location->priority,
2708
                'sortField' => $location->sortField,
2709
                'sortOrder' => $location->sortOrder,
2710
            ),
2711
            $overwrite
2712
        );
2713
    }
2714
2715
    /**
2716
     * Assert generated aliases to expected alias return.
2717
     *
2718
     * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
2719
     * @param array $expectedAliases
2720
     */
2721
    protected function assertGeneratedAliases($urlAliasService, array $expectedAliases)
2722
    {
2723
        foreach ($expectedAliases as $expectedAlias) {
2724
            $urlAlias = $urlAliasService->lookup($expectedAlias);
2725
            $this->assertPropertiesCorrect(['type' => 0], $urlAlias);
2726
        }
2727
    }
2728
2729
    /**
2730
     * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
2731
     * @param array $expectedSubItemAliases
2732
     */
2733
    private function assertAliasesBeforeCopy($urlAliasService, array $expectedSubItemAliases)
2734
    {
2735
        foreach ($expectedSubItemAliases as $aliasUrl) {
2736
            try {
2737
                $urlAliasService->lookup($aliasUrl);
2738
                $this->fail('We didn\'t expect to find alias, but it was found');
2739
            } catch (\Exception $e) {
2740
                $this->assertTrue(true); // OK - alias was not found
2741
            }
2742
        }
2743
    }
2744
2745
    /**
2746
     * Create and publish Content with the given parent Location.
2747
     *
2748
     * @param string $contentName
2749
     * @param int $parentLocationId
2750
     *
2751
     * @return \eZ\Publish\API\Repository\Values\Content\Content published Content
2752
     */
2753 View Code Duplication
    private function publishContentWithParentLocation($contentName, $parentLocationId)
2754
    {
2755
        $repository = $this->getRepository(false);
2756
        $locationService = $repository->getLocationService();
2757
2758
        $contentService = $repository->getContentService();
2759
        $contentTypeService = $repository->getContentTypeService();
2760
2761
        $contentCreateStruct = $contentService->newContentCreateStruct(
2762
            $contentTypeService->loadContentTypeByIdentifier('folder'),
2763
            'eng-US'
2764
        );
2765
        $contentCreateStruct->setField('name', $contentName);
2766
        $contentDraft = $contentService->createContent(
2767
            $contentCreateStruct,
2768
            [
2769
                $locationService->newLocationCreateStruct($parentLocationId),
2770
            ]
2771
        );
2772
2773
        return $contentService->publishVersion($contentDraft->versionInfo);
2774
    }
2775
}
2776