Completed
Push — location_multi_load ( e5e305 )
by André
32:49 queued 12:49
created

LocationServiceTest::testLoadLocationList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

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

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

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

Loading history...
613
        self::assertEquals([5], array_keys($locations));
614
        self::assertInstanceOf(Location::class, $locations[5]);
615
        self::assertEquals(5, $locations[5]->id);
616
    }
617
618
    /**
619
     * Test for the loadLocationByRemoteId() method.
620
     *
621
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationByRemoteId()
622
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
623
     */
624 View Code Duplication
    public function testLoadLocationByRemoteId()
625
    {
626
        $repository = $this->getRepository();
627
628
        /* BEGIN: Use Case */
629
        $locationService = $repository->getLocationService();
630
631
        $location = $locationService->loadLocationByRemoteId(
632
            '3f6d92f8044aed134f32153517850f5a'
633
        );
634
        /* END: Use Case */
635
636
        $this->assertEquals(
637
            $locationService->loadLocation($this->generateId('location', 5)),
638
            $location
639
        );
640
    }
641
642
    /**
643
     * Test for the loadLocationByRemoteId() method.
644
     *
645
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationByRemoteId()
646
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
647
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
648
     */
649
    public function testLoadLocationByRemoteIdThrowsNotFoundException()
650
    {
651
        $repository = $this->getRepository();
652
653
        /* BEGIN: Use Case */
654
        $locationService = $repository->getLocationService();
655
656
        // Throws exception, since Location with remote ID does not exist
657
        $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...
658
            'not-exists'
659
        );
660
        /* END: Use Case */
661
    }
662
663
    /**
664
     * Test for the loadLocations() method.
665
     *
666
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
667
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
668
     */
669
    public function testLoadLocations()
670
    {
671
        $repository = $this->getRepository();
672
673
        $contentId = $this->generateId('object', 4);
674
        /* BEGIN: Use Case */
675
        // $contentId contains the ID of an existing content object
676
        $contentService = $repository->getContentService();
677
        $locationService = $repository->getLocationService();
678
679
        $contentInfo = $contentService->loadContentInfo($contentId);
680
681
        $locations = $locationService->loadLocations($contentInfo);
682
        /* END: Use Case */
683
684
        $this->assertInternalType('array', $locations);
685
        self::assertNotEmpty($locations);
686
687
        foreach ($locations as $location) {
688
            self::assertInstanceOf(Location::class, $location);
689
            self::assertEquals($contentInfo->id, $location->getContentInfo()->id);
690
        }
691
692
        return $locations;
693
    }
694
695
    /**
696
     * Test for the loadLocations() method.
697
     *
698
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
699
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
700
     */
701
    public function testLoadLocationsContent(array $locations)
702
    {
703
        $repository = $this->getRepository();
704
        $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...
705
706
        $this->assertEquals(1, count($locations));
707
        foreach ($locations as $loadedLocation) {
708
            $this->assertInstanceOf(
709
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
710
                $loadedLocation
711
            );
712
        }
713
714
        usort(
715
            $locations,
716
            function ($a, $b) {
717
                strcmp($a->id, $b->id);
718
            }
719
        );
720
721
        $this->assertEquals(
722
            array($this->generateId('location', 5)),
723
            array_map(
724
                function (Location $location) {
725
                    return $location->id;
726
                },
727
                $locations
728
            )
729
        );
730
    }
731
732
    /**
733
     * Test for the loadLocations() method.
734
     *
735
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
736
     *
737
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations($contentInfo, $rootLocation)
738
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
739
     */
740
    public function testLoadLocationsLimitedSubtree()
741
    {
742
        $repository = $this->getRepository();
743
744
        $originalLocationId = $this->generateId('location', 54);
745
        $originalParentLocationId = $this->generateId('location', 48);
746
        $newParentLocationId = $this->generateId('location', 43);
747
        /* BEGIN: Use Case */
748
        // $originalLocationId is the ID of an existing location
749
        // $originalParentLocationId is the ID of the parent location of
750
        //     $originalLocationId
751
        // $newParentLocationId is the ID of an existing location outside the tree
752
        // of $originalLocationId and $originalParentLocationId
753
        $locationService = $repository->getLocationService();
754
755
        // Location at "/1/48/54"
756
        $originalLocation = $locationService->loadLocation($originalLocationId);
757
758
        // Create location under "/1/43/"
759
        $locationCreate = $locationService->newLocationCreateStruct($newParentLocationId);
760
        $locationService->createLocation(
761
            $originalLocation->contentInfo,
762
            $locationCreate
763
        );
764
765
        $findRootLocation = $locationService->loadLocation($originalParentLocationId);
766
767
        // Returns an array with only $originalLocation
768
        $locations = $locationService->loadLocations(
769
            $originalLocation->contentInfo,
770
            $findRootLocation
771
        );
772
        /* END: Use Case */
773
774
        $this->assertInternalType('array', $locations);
775
776
        return $locations;
777
    }
778
779
    /**
780
     * Test for the loadLocations() method.
781
     *
782
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
783
     *
784
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
785
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationsLimitedSubtree
786
     */
787
    public function testLoadLocationsLimitedSubtreeContent(array $locations)
788
    {
789
        $this->assertEquals(1, count($locations));
790
791
        $this->assertEquals(
792
            $this->generateId('location', 54),
793
            reset($locations)->id
794
        );
795
    }
796
797
    /**
798
     * Test for the loadLocations() method.
799
     *
800
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
801
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
802
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
803
     */
804 View Code Duplication
    public function testLoadLocationsThrowsBadStateException()
805
    {
806
        $repository = $this->getRepository();
807
808
        /* BEGIN: Use Case */
809
        $contentTypeService = $repository->getContentTypeService();
810
        $contentService = $repository->getContentService();
811
        $locationService = $repository->getLocationService();
812
813
        // Create new content, which is not published
814
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
815
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
816
        $contentCreate->setField('name', 'New Folder');
817
        $content = $contentService->createContent($contentCreate);
818
819
        // Throws Exception, since $content has no published version, yet
820
        $locationService->loadLocations(
821
            $content->contentInfo
822
        );
823
        /* END: Use Case */
824
    }
825
826
    /**
827
     * Test for the loadLocations() method.
828
     *
829
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations($contentInfo, $rootLocation)
830
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
831
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
832
     */
833
    public function testLoadLocationsThrowsBadStateExceptionLimitedSubtree()
834
    {
835
        $repository = $this->getRepository();
836
837
        $someLocationId = $this->generateId('location', 2);
838
        /* BEGIN: Use Case */
839
        // $someLocationId is the ID of an existing location
840
        $contentTypeService = $repository->getContentTypeService();
841
        $contentService = $repository->getContentService();
842
        $locationService = $repository->getLocationService();
843
844
        // Create new content, which is not published
845
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
846
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
847
        $contentCreate->setField('name', 'New Folder');
848
        $content = $contentService->createContent($contentCreate);
849
850
        $findRootLocation = $locationService->loadLocation($someLocationId);
851
852
        // Throws Exception, since $content has no published version, yet
853
        $locationService->loadLocations(
854
            $content->contentInfo,
855
            $findRootLocation
856
        );
857
        /* END: Use Case */
858
    }
859
860
    /**
861
     * Test for the loadLocationChildren() method.
862
     *
863
     * @covers \eZ\Publish\API\Repository\LocationService::loadLocationChildren
864
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
865
     */
866
    public function testLoadLocationChildren()
867
    {
868
        $repository = $this->getRepository();
869
870
        $locationId = $this->generateId('location', 5);
871
        /* BEGIN: Use Case */
872
        // $locationId is the ID of an existing location
873
        $locationService = $repository->getLocationService();
874
875
        $location = $locationService->loadLocation($locationId);
876
877
        $childLocations = $locationService->loadLocationChildren($location);
878
        /* END: Use Case */
879
880
        $this->assertInstanceOf(LocationList::class, $childLocations);
881
        $this->assertInternalType('array', $childLocations->locations);
882
        $this->assertNotEmpty($childLocations->locations);
883
        $this->assertInternalType('int', $childLocations->totalCount);
884
885
        foreach ($childLocations->locations as $childLocation) {
886
            $this->assertInstanceOf(Location::class, $childLocation);
887
            $this->assertEquals($location->id, $childLocation->parentLocationId);
888
        }
889
890
        return $childLocations;
891
    }
892
893
    /**
894
     * Test loading parent Locations for draft Content.
895
     *
896
     * @covers \eZ\Publish\API\Repository\LocationService::loadParentLocationsForDraftContent
897
     */
898
    public function testLoadParentLocationsForDraftContent()
899
    {
900
        $repository = $this->getRepository();
901
        $locationService = $repository->getLocationService();
902
        $contentService = $repository->getContentService();
903
        $contentTypeService = $repository->getContentTypeService();
904
905
        // prepare locations
906
        $locationCreateStructs = [
907
            $locationService->newLocationCreateStruct(2),
908
            $locationService->newLocationCreateStruct(5),
909
        ];
910
911
        // Create new content
912
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
913
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
914
        $contentCreate->setField('name', 'New Folder');
915
        $contentDraft = $contentService->createContent($contentCreate, $locationCreateStructs);
916
917
        // Test loading parent Locations
918
        $locations = $locationService->loadParentLocationsForDraftContent($contentDraft->versionInfo);
919
920
        self::assertCount(2, $locations);
921
        foreach ($locations as $location) {
922
            // test it is one of the given parent locations
923
            self::assertTrue($location->id === 2 || $location->id === 5);
924
        }
925
926
        return $contentDraft;
927
    }
928
929
    /**
930
     * Test that trying to load parent Locations throws Exception if Content is not a draft.
931
     *
932
     * @depends testLoadParentLocationsForDraftContent
933
     *
934
     * @param \eZ\Publish\API\Repository\Values\Content\Content $contentDraft
935
     */
936
    public function testLoadParentLocationsForDraftContentThrowsBadStateException(Content $contentDraft)
937
    {
938
        $this->expectException(BadStateException::class);
939
        $this->expectExceptionMessageRegExp('/has been already published/');
940
941
        $repository = $this->getRepository(false);
942
        $locationService = $repository->getLocationService();
943
        $contentService = $repository->getContentService();
944
945
        $content = $contentService->publishVersion($contentDraft->versionInfo);
946
947
        $locationService->loadParentLocationsForDraftContent($content->versionInfo);
948
    }
949
950
    /**
951
     * Test for the getLocationChildCount() method.
952
     *
953
     * @see \eZ\Publish\API\Repository\LocationService::getLocationChildCount()
954
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
955
     */
956
    public function testGetLocationChildCount()
957
    {
958
        // $locationId is the ID of an existing location
959
        $locationService = $this->getRepository()->getLocationService();
960
961
        $this->assertSame(
962
            5,
963
            $locationService->getLocationChildCount(
964
                $locationService->loadLocation($this->generateId('location', 5))
965
            )
966
        );
967
    }
968
969
    /**
970
     * Test for the loadLocationChildren() method.
971
     *
972
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren()
973
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
974
     */
975
    public function testLoadLocationChildrenData(LocationList $locations)
976
    {
977
        $this->assertEquals(5, count($locations->locations));
978
        $this->assertEquals(5, $locations->totalCount);
979
980
        foreach ($locations->locations as $location) {
981
            $this->assertInstanceOf(
982
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
983
                $location
984
            );
985
        }
986
987
        $this->assertEquals(
988
            array(
989
                $this->generateId('location', 12),
990
                $this->generateId('location', 13),
991
                $this->generateId('location', 14),
992
                $this->generateId('location', 44),
993
                $this->generateId('location', 61),
994
            ),
995
            array_map(
996
                function (Location $location) {
997
                    return $location->id;
998
                },
999
                $locations->locations
1000
            )
1001
        );
1002
    }
1003
1004
    /**
1005
     * Test for the loadLocationChildren() method.
1006
     *
1007
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
1008
     *
1009
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset)
1010
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
1011
     */
1012 View Code Duplication
    public function testLoadLocationChildrenWithOffset()
1013
    {
1014
        $repository = $this->getRepository();
1015
1016
        $locationId = $this->generateId('location', 5);
1017
        /* BEGIN: Use Case */
1018
        // $locationId is the ID of an existing location
1019
        $locationService = $repository->getLocationService();
1020
1021
        $location = $locationService->loadLocation($locationId);
1022
1023
        $childLocations = $locationService->loadLocationChildren($location, 2);
1024
        /* END: Use Case */
1025
1026
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
1027
        $this->assertInternalType('array', $childLocations->locations);
1028
        $this->assertInternalType('int', $childLocations->totalCount);
1029
1030
        return $childLocations;
1031
    }
1032
1033
    /**
1034
     * Test for the loadLocationChildren() method.
1035
     *
1036
     * @param \eZ\Publish\API\Repository\Values\Content\LocationList $locations
1037
     *
1038
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset)
1039
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildrenWithOffset
1040
     */
1041 View Code Duplication
    public function testLoadLocationChildrenDataWithOffset(LocationList $locations)
1042
    {
1043
        $this->assertEquals(3, count($locations->locations));
1044
        $this->assertEquals(5, $locations->totalCount);
1045
1046
        foreach ($locations->locations as $location) {
1047
            $this->assertInstanceOf(
1048
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1049
                $location
1050
            );
1051
        }
1052
1053
        $this->assertEquals(
1054
            array(
1055
                $this->generateId('location', 14),
1056
                $this->generateId('location', 44),
1057
                $this->generateId('location', 61),
1058
            ),
1059
            array_map(
1060
                function (Location $location) {
1061
                    return $location->id;
1062
                },
1063
                $locations->locations
1064
            )
1065
        );
1066
    }
1067
1068
    /**
1069
     * Test for the loadLocationChildren() method.
1070
     *
1071
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
1072
     *
1073
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset, $limit)
1074
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
1075
     */
1076 View Code Duplication
    public function testLoadLocationChildrenWithOffsetAndLimit()
1077
    {
1078
        $repository = $this->getRepository();
1079
1080
        $locationId = $this->generateId('location', 5);
1081
        /* BEGIN: Use Case */
1082
        // $locationId is the ID of an existing location
1083
        $locationService = $repository->getLocationService();
1084
1085
        $location = $locationService->loadLocation($locationId);
1086
1087
        $childLocations = $locationService->loadLocationChildren($location, 2, 2);
1088
        /* END: Use Case */
1089
1090
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
1091
        $this->assertInternalType('array', $childLocations->locations);
1092
        $this->assertInternalType('int', $childLocations->totalCount);
1093
1094
        return $childLocations;
1095
    }
1096
1097
    /**
1098
     * Test for the loadLocationChildren() method.
1099
     *
1100
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
1101
     *
1102
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset, $limit)
1103
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildrenWithOffsetAndLimit
1104
     */
1105 View Code Duplication
    public function testLoadLocationChildrenDataWithOffsetAndLimit(LocationList $locations)
1106
    {
1107
        $this->assertEquals(2, count($locations->locations));
1108
        $this->assertEquals(5, $locations->totalCount);
1109
1110
        foreach ($locations->locations as $location) {
1111
            $this->assertInstanceOf(
1112
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1113
                $location
1114
            );
1115
        }
1116
1117
        $this->assertEquals(
1118
            array(
1119
                $this->generateId('location', 14),
1120
                $this->generateId('location', 44),
1121
            ),
1122
            array_map(
1123
                function (Location $location) {
1124
                    return $location->id;
1125
                },
1126
                $locations->locations
1127
            )
1128
        );
1129
    }
1130
1131
    /**
1132
     * Test for the newLocationUpdateStruct() method.
1133
     *
1134
     * @covers \eZ\Publish\API\Repository\LocationService::newLocationUpdateStruct
1135
     */
1136 View Code Duplication
    public function testNewLocationUpdateStruct()
1137
    {
1138
        $repository = $this->getRepository();
1139
1140
        /* BEGIN: Use Case */
1141
        $locationService = $repository->getLocationService();
1142
1143
        $updateStruct = $locationService->newLocationUpdateStruct();
1144
        /* END: Use Case */
1145
1146
        $this->assertInstanceOf(
1147
            LocationUpdateStruct::class,
1148
            $updateStruct
1149
        );
1150
1151
        $this->assertPropertiesCorrect(
1152
            [
1153
                'priority' => null,
1154
                'remoteId' => null,
1155
                'sortField' => null,
1156
                'sortOrder' => null,
1157
            ],
1158
            $updateStruct
1159
        );
1160
    }
1161
1162
    /**
1163
     * Test for the updateLocation() method.
1164
     *
1165
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1166
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1167
     */
1168
    public function testUpdateLocation()
1169
    {
1170
        $repository = $this->getRepository();
1171
1172
        $originalLocationId = $this->generateId('location', 5);
1173
        /* BEGIN: Use Case */
1174
        // $originalLocationId is the ID of an existing location
1175
        $locationService = $repository->getLocationService();
1176
1177
        $originalLocation = $locationService->loadLocation($originalLocationId);
1178
1179
        $updateStruct = $locationService->newLocationUpdateStruct();
1180
        $updateStruct->priority = 3;
1181
        $updateStruct->remoteId = 'c7adcbf1e96bc29bca28c2d809d0c7ef69272651';
1182
        $updateStruct->sortField = Location::SORT_FIELD_PRIORITY;
1183
        $updateStruct->sortOrder = Location::SORT_ORDER_DESC;
1184
1185
        $updatedLocation = $locationService->updateLocation($originalLocation, $updateStruct);
1186
        /* END: Use Case */
1187
1188
        $this->assertInstanceOf(
1189
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1190
            $updatedLocation
1191
        );
1192
1193
        return array(
1194
            'originalLocation' => $originalLocation,
1195
            'updateStruct' => $updateStruct,
1196
            'updatedLocation' => $updatedLocation,
1197
        );
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::testUpdateLocation
1205
     */
1206
    public function testUpdateLocationStructValues(array $data)
1207
    {
1208
        $originalLocation = $data['originalLocation'];
1209
        $updateStruct = $data['updateStruct'];
1210
        $updatedLocation = $data['updatedLocation'];
1211
1212
        $this->assertPropertiesCorrect(
1213
            array(
1214
                'id' => $originalLocation->id,
1215
                'priority' => $updateStruct->priority,
1216
                'hidden' => $originalLocation->hidden,
1217
                'invisible' => $originalLocation->invisible,
1218
                'remoteId' => $updateStruct->remoteId,
1219
                'contentInfo' => $originalLocation->contentInfo,
1220
                'parentLocationId' => $originalLocation->parentLocationId,
1221
                'pathString' => $originalLocation->pathString,
1222
                'depth' => $originalLocation->depth,
1223
                'sortField' => $updateStruct->sortField,
1224
                'sortOrder' => $updateStruct->sortOrder,
1225
            ),
1226
            $updatedLocation
1227
        );
1228
    }
1229
1230
    /**
1231
     * Test for the updateLocation() method.
1232
     *
1233
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1234
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1235
     */
1236
    public function testUpdateLocationWithSameRemoteId()
1237
    {
1238
        $repository = $this->getRepository();
1239
1240
        $locationId = $this->generateId('location', 5);
1241
        /* BEGIN: Use Case */
1242
        // $locationId and remote ID is the IDs of the same, existing location
1243
        $locationService = $repository->getLocationService();
1244
1245
        $originalLocation = $locationService->loadLocation($locationId);
1246
1247
        $updateStruct = $locationService->newLocationUpdateStruct();
1248
1249
        // Remote ID of an existing location with the same locationId
1250
        $updateStruct->remoteId = $originalLocation->remoteId;
1251
1252
        // Sets one of the properties to be able to confirm location gets updated, here: priority
1253
        $updateStruct->priority = 2;
1254
1255
        $location = $locationService->updateLocation($originalLocation, $updateStruct);
1256
1257
        // Checks that the location was updated
1258
        $this->assertEquals(2, $location->priority);
1259
1260
        // Checks that remoteId remains the same
1261
        $this->assertEquals($originalLocation->remoteId, $location->remoteId);
1262
        /* END: Use Case */
1263
    }
1264
1265
    /**
1266
     * Test for the updateLocation() method.
1267
     *
1268
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1269
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1270
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1271
     */
1272 View Code Duplication
    public function testUpdateLocationThrowsInvalidArgumentException()
1273
    {
1274
        $repository = $this->getRepository();
1275
1276
        $locationId = $this->generateId('location', 5);
1277
        /* BEGIN: Use Case */
1278
        // $locationId and remoteId is the IDs of an existing, but not the same, location
1279
        $locationService = $repository->getLocationService();
1280
1281
        $originalLocation = $locationService->loadLocation($locationId);
1282
1283
        $updateStruct = $locationService->newLocationUpdateStruct();
1284
1285
        // Remote ID of an existing location with a different locationId
1286
        $updateStruct->remoteId = 'f3e90596361e31d496d4026eb624c983';
1287
1288
        // Throws exception, since remote ID is already taken
1289
        $locationService->updateLocation($originalLocation, $updateStruct);
1290
        /* END: Use Case */
1291
    }
1292
1293
    /**
1294
     * Test for the updateLocation() method.
1295
     *
1296
     * @covers \eZ\Publish\API\Repository\LocationService::updateLocation()
1297
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1298
     * @dataProvider dataProviderForOutOfRangeLocationPriority
1299
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1300
     */
1301
    public function testUpdateLocationThrowsInvalidArgumentExceptionPriorityIsOutOfRange($priority)
1302
    {
1303
        $repository = $this->getRepository();
1304
1305
        $locationId = $this->generateId('location', 5);
1306
        /* BEGIN: Use Case */
1307
        // $locationId and remoteId is the IDs of an existing, but not the same, location
1308
        $locationService = $repository->getLocationService();
1309
1310
        $originalLocation = $locationService->loadLocation($locationId);
1311
1312
        $updateStruct = $locationService->newLocationUpdateStruct();
1313
1314
        // Priority value is out of range
1315
        $updateStruct->priority = $priority;
1316
1317
        // Throws exception, since remote ID is already taken
1318
        $locationService->updateLocation($originalLocation, $updateStruct);
1319
        /* END: Use Case */
1320
    }
1321
1322
    /**
1323
     * Test for the updateLocation() method.
1324
     * Ref EZP-23302: Update Location fails if no change is performed with the update.
1325
     *
1326
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1327
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1328
     */
1329
    public function testUpdateLocationTwice()
1330
    {
1331
        $repository = $this->getRepository();
1332
1333
        $locationId = $this->generateId('location', 5);
1334
        /* BEGIN: Use Case */
1335
        $locationService = $repository->getLocationService();
1336
        $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...
1337
1338
        $originalLocation = $locationService->loadLocation($locationId);
1339
1340
        $updateStruct = $locationService->newLocationUpdateStruct();
1341
        $updateStruct->priority = 42;
1342
1343
        $updatedLocation = $locationService->updateLocation($originalLocation, $updateStruct);
1344
1345
        // Repeated update with the same, unchanged struct
1346
        $secondUpdatedLocation = $locationService->updateLocation($updatedLocation, $updateStruct);
1347
        /* END: Use Case */
1348
1349
        $this->assertEquals($updatedLocation->priority, 42);
1350
        $this->assertEquals($secondUpdatedLocation->priority, 42);
1351
    }
1352
1353
    /**
1354
     * Test for the swapLocation() method.
1355
     *
1356
     * @see \eZ\Publish\API\Repository\LocationService::swapLocation()
1357
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1358
     */
1359
    public function testSwapLocation()
1360
    {
1361
        $repository = $this->getRepository();
1362
        $locationService = $repository->getLocationService();
1363
1364
        $mediaLocationId = $this->generateId('location', 43);
1365
        $demoDesignLocationId = $this->generateId('location', 56);
1366
1367
        $mediaContentInfo = $locationService->loadLocation($mediaLocationId)->getContentInfo();
1368
        $demoDesignContentInfo = $locationService->loadLocation($demoDesignLocationId)->getContentInfo();
1369
1370
        /* BEGIN: Use Case */
1371
        // $mediaLocationId is the ID of the "Media" page location in
1372
        // an eZ Publish demo installation
1373
1374
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1375
        // Publish demo installation
1376
1377
        // Load the location service
1378
        $locationService = $repository->getLocationService();
1379
1380
        $mediaLocation = $locationService->loadLocation($mediaLocationId);
1381
        $demoDesignLocation = $locationService->loadLocation($demoDesignLocationId);
1382
1383
        // Swaps the content referred to by the locations
1384
        $locationService->swapLocation($mediaLocation, $demoDesignLocation);
1385
        /* END: Use Case */
1386
1387
        // Reload Locations, IDs swapped
1388
        $demoDesignLocation = $locationService->loadLocation($mediaLocationId);
1389
        $mediaLocation = $locationService->loadLocation($demoDesignLocationId);
1390
1391
        // Assert Location's Content is updated
1392
        $this->assertEquals(
1393
            $mediaContentInfo->id,
1394
            $mediaLocation->getContentInfo()->id
1395
        );
1396
        $this->assertEquals(
1397
            $demoDesignContentInfo->id,
1398
            $demoDesignLocation->getContentInfo()->id
1399
        );
1400
1401
        // Assert URL aliases are updated
1402
        $this->assertEquals(
1403
            $mediaLocation->id,
1404
            $repository->getURLAliasService()->lookup('/Design/Media')->destination
1405
        );
1406
        $this->assertEquals(
1407
            $demoDesignLocation->id,
1408
            $repository->getURLAliasService()->lookup('/eZ-Publish-Demo-Design-without-demo-content')->destination
1409
        );
1410
    }
1411
1412
    /**
1413
     * Test swapping Main Location of a Content with another one updates Content item Main Location.
1414
     *
1415
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1416
     */
1417
    public function testSwapLocationUpdatesMainLocation()
1418
    {
1419
        $repository = $this->getRepository();
1420
        $locationService = $repository->getLocationService();
1421
        $contentService = $repository->getContentService();
1422
1423
        $mainLocationParentId = 60;
1424
        $secondaryLocationId = 43;
1425
1426
        $publishedContent = $this->publishContentWithParentLocation(
1427
            'Content for Swap Location Test', $mainLocationParentId
1428
        );
1429
1430
        // sanity check
1431
        $mainLocation = $locationService->loadLocation($publishedContent->contentInfo->mainLocationId);
1432
        self::assertEquals($mainLocationParentId, $mainLocation->parentLocationId);
1433
1434
        // load another pre-existing location
1435
        $secondaryLocation = $locationService->loadLocation($secondaryLocationId);
1436
1437
        // swap the Main Location with a secondary one
1438
        $locationService->swapLocation($mainLocation, $secondaryLocation);
1439
1440
        // check if Main Location has been updated
1441
        $mainLocation = $locationService->loadLocation($secondaryLocation->id);
1442
        self::assertEquals($publishedContent->contentInfo->id, $mainLocation->contentInfo->id);
1443
        self::assertEquals($mainLocation->id, $mainLocation->contentInfo->mainLocationId);
1444
1445
        $reloadedContent = $contentService->loadContentByContentInfo($publishedContent->contentInfo);
1446
        self::assertEquals($mainLocation->id, $reloadedContent->contentInfo->mainLocationId);
1447
    }
1448
1449
    /**
1450
     * Test if location swap affects related bookmarks.
1451
     *
1452
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1453
     */
1454
    public function testBookmarksAreSwappedAfterSwapLocation()
1455
    {
1456
        $repository = $this->getRepository();
1457
1458
        $mediaLocationId = $this->generateId('location', 43);
1459
        $demoDesignLocationId = $this->generateId('location', 56);
1460
1461
        /* BEGIN: Use Case */
1462
        $locationService = $repository->getLocationService();
1463
        $bookmarkService = $repository->getBookmarkService();
1464
1465
        $mediaLocation = $locationService->loadLocation($mediaLocationId);
1466
        $demoDesignLocation = $locationService->loadLocation($demoDesignLocationId);
1467
1468
        // Bookmark locations
1469
        $bookmarkService->createBookmark($mediaLocation);
1470
        $bookmarkService->createBookmark($demoDesignLocation);
1471
1472
        $beforeSwap = $bookmarkService->loadBookmarks();
1473
1474
        // Swaps the content referred to by the locations
1475
        $locationService->swapLocation($mediaLocation, $demoDesignLocation);
1476
1477
        $afterSwap = $bookmarkService->loadBookmarks();
1478
        /* END: Use Case */
1479
1480
        $this->assertEquals($beforeSwap->items[0]->id, $afterSwap->items[1]->id);
1481
        $this->assertEquals($beforeSwap->items[1]->id, $afterSwap->items[0]->id);
1482
    }
1483
1484
    /**
1485
     * Test for the hideLocation() method.
1486
     *
1487
     * @see \eZ\Publish\API\Repository\LocationService::hideLocation()
1488
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1489
     */
1490
    public function testHideLocation()
1491
    {
1492
        $repository = $this->getRepository();
1493
1494
        $locationId = $this->generateId('location', 5);
1495
        /* BEGIN: Use Case */
1496
        // $locationId is the ID of an existing location
1497
        $locationService = $repository->getLocationService();
1498
1499
        $visibleLocation = $locationService->loadLocation($locationId);
1500
1501
        $hiddenLocation = $locationService->hideLocation($visibleLocation);
1502
        /* END: Use Case */
1503
1504
        $this->assertInstanceOf(
1505
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1506
            $hiddenLocation
1507
        );
1508
1509
        $this->assertTrue(
1510
            $hiddenLocation->hidden,
1511
            sprintf(
1512
                'Location with ID "%s" not hidden.',
1513
                $hiddenLocation->id
1514
            )
1515
        );
1516
1517
        $this->refreshSearch($repository);
1518
1519
        foreach ($locationService->loadLocationChildren($hiddenLocation)->locations as $child) {
1520
            $this->assertSubtreeProperties(
1521
                array('invisible' => true),
1522
                $child
1523
            );
1524
        }
1525
    }
1526
1527
    /**
1528
     * Assert that $expectedValues are set in the subtree starting at $location.
1529
     *
1530
     * @param array $expectedValues
1531
     * @param Location $location
1532
     */
1533
    protected function assertSubtreeProperties(array $expectedValues, Location $location, $stopId = null)
1534
    {
1535
        $repository = $this->getRepository();
1536
        $locationService = $repository->getLocationService();
1537
1538
        if ($location->id === $stopId) {
1539
            return;
1540
        }
1541
1542
        foreach ($expectedValues as $propertyName => $propertyValue) {
1543
            $this->assertEquals(
1544
                $propertyValue,
1545
                $location->$propertyName
1546
            );
1547
1548
            foreach ($locationService->loadLocationChildren($location)->locations as $child) {
1549
                $this->assertSubtreeProperties($expectedValues, $child);
1550
            }
1551
        }
1552
    }
1553
1554
    /**
1555
     * Test for the unhideLocation() method.
1556
     *
1557
     * @see \eZ\Publish\API\Repository\LocationService::unhideLocation()
1558
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testHideLocation
1559
     */
1560
    public function testUnhideLocation()
1561
    {
1562
        $repository = $this->getRepository();
1563
1564
        $locationId = $this->generateId('location', 5);
1565
        /* BEGIN: Use Case */
1566
        // $locationId is the ID of an existing location
1567
        $locationService = $repository->getLocationService();
1568
1569
        $visibleLocation = $locationService->loadLocation($locationId);
1570
        $hiddenLocation = $locationService->hideLocation($visibleLocation);
1571
1572
        $unHiddenLocation = $locationService->unhideLocation($hiddenLocation);
1573
        /* END: Use Case */
1574
1575
        $this->assertInstanceOf(
1576
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1577
            $unHiddenLocation
1578
        );
1579
1580
        $this->assertFalse(
1581
            $unHiddenLocation->hidden,
1582
            sprintf(
1583
                'Location with ID "%s" not unhidden.',
1584
                $unHiddenLocation->id
1585
            )
1586
        );
1587
1588
        $this->refreshSearch($repository);
1589
1590
        foreach ($locationService->loadLocationChildren($unHiddenLocation)->locations as $child) {
1591
            $this->assertSubtreeProperties(
1592
                array('invisible' => false),
1593
                $child
1594
            );
1595
        }
1596
    }
1597
1598
    /**
1599
     * Test for the unhideLocation() method.
1600
     *
1601
     * @see \eZ\Publish\API\Repository\LocationService::unhideLocation()
1602
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testUnhideLocation
1603
     */
1604
    public function testUnhideLocationNotUnhidesHiddenSubtree()
1605
    {
1606
        $repository = $this->getRepository();
1607
1608
        $higherLocationId = $this->generateId('location', 5);
1609
        $lowerLocationId = $this->generateId('location', 13);
1610
        /* BEGIN: Use Case */
1611
        // $higherLocationId is the ID of a location
1612
        // $lowerLocationId is the ID of a location below $higherLocationId
1613
        $locationService = $repository->getLocationService();
1614
1615
        $higherLocation = $locationService->loadLocation($higherLocationId);
1616
        $hiddenHigherLocation = $locationService->hideLocation($higherLocation);
1617
1618
        $lowerLocation = $locationService->loadLocation($lowerLocationId);
1619
        $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...
1620
1621
        $unHiddenHigherLocation = $locationService->unhideLocation($hiddenHigherLocation);
1622
        /* END: Use Case */
1623
1624
        $this->assertInstanceOf(
1625
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1626
            $unHiddenHigherLocation
1627
        );
1628
1629
        $this->assertFalse(
1630
            $unHiddenHigherLocation->hidden,
1631
            sprintf(
1632
                'Location with ID "%s" not unhidden.',
1633
                $unHiddenHigherLocation->id
1634
            )
1635
        );
1636
1637
        $this->refreshSearch($repository);
1638
1639
        foreach ($locationService->loadLocationChildren($unHiddenHigherLocation)->locations as $child) {
1640
            $this->assertSubtreeProperties(
1641
                array('invisible' => false),
1642
                $child,
1643
                $this->generateId('location', 13)
1644
            );
1645
        }
1646
1647
        $stillHiddenLocation = $locationService->loadLocation($this->generateId('location', 13));
1648
        $this->assertTrue(
1649
            $stillHiddenLocation->hidden,
1650
            sprintf(
1651
                'Hidden sub-location with ID %s accidentally unhidden.',
1652
                $stillHiddenLocation->id
1653
            )
1654
        );
1655
        foreach ($locationService->loadLocationChildren($stillHiddenLocation)->locations as $child) {
1656
            $this->assertSubtreeProperties(
1657
                array('invisible' => true),
1658
                $child
1659
            );
1660
        }
1661
    }
1662
1663
    /**
1664
     * Test for the deleteLocation() method.
1665
     *
1666
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1667
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1668
     */
1669
    public function testDeleteLocation()
1670
    {
1671
        $repository = $this->getRepository();
1672
1673
        $mediaLocationId = $this->generateId('location', 43);
1674
        /* BEGIN: Use Case */
1675
        // $mediaLocationId is the ID of the location of the
1676
        // "Media" location in an eZ Publish demo installation
1677
        $locationService = $repository->getLocationService();
1678
1679
        $location = $locationService->loadLocation($mediaLocationId);
1680
1681
        $locationService->deleteLocation($location);
1682
        /* END: Use Case */
1683
1684
        try {
1685
            $locationService->loadLocation($mediaLocationId);
1686
            $this->fail("Location $mediaLocationId not deleted.");
1687
        } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1688
        }
1689
1690
        // The following IDs are IDs of child locations of $mediaLocationId location
1691
        // ( Media/Images, Media/Files, Media/Multimedia respectively )
1692
        foreach (array(51, 52, 53) as $childLocationId) {
1693
            try {
1694
                $locationService->loadLocation($this->generateId('location', $childLocationId));
1695
                $this->fail("Location $childLocationId not deleted.");
1696
            } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1697
            }
1698
        }
1699
1700
        // The following IDs are IDs of content below $mediaLocationId location
1701
        // ( Media/Images, Media/Files, Media/Multimedia respectively )
1702
        $contentService = $this->getRepository()->getContentService();
1703
        foreach (array(49, 50, 51) as $childContentId) {
1704
            try {
1705
                $contentService->loadContentInfo($this->generateId('object', $childContentId));
1706
                $this->fail("Content $childContentId not deleted.");
1707
            } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1708
            }
1709
        }
1710
    }
1711
1712
    /**
1713
     * Test for the deleteLocation() method.
1714
     *
1715
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1716
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testDeleteLocation
1717
     */
1718
    public function testDeleteLocationDecrementsChildCountOnParent()
1719
    {
1720
        $repository = $this->getRepository();
1721
1722
        $mediaLocationId = $this->generateId('location', 43);
1723
        /* BEGIN: Use Case */
1724
        // $mediaLocationId is the ID of the location of the
1725
        // "Media" location in an eZ Publish demo installation
1726
1727
        $locationService = $repository->getLocationService();
1728
1729
        // Load the current the user group location
1730
        $location = $locationService->loadLocation($mediaLocationId);
1731
1732
        // Load the parent location
1733
        $parentLocation = $locationService->loadLocation(
1734
            $location->parentLocationId
1735
        );
1736
1737
        // Get child count
1738
        $childCountBefore = $locationService->getLocationChildCount($parentLocation);
1739
1740
        // Delete the user group location
1741
        $locationService->deleteLocation($location);
1742
1743
        $this->refreshSearch($repository);
1744
1745
        // Reload parent location
1746
        $parentLocation = $locationService->loadLocation(
1747
            $location->parentLocationId
1748
        );
1749
1750
        // This will be $childCountBefore - 1
1751
        $childCountAfter = $locationService->getLocationChildCount($parentLocation);
1752
        /* END: Use Case */
1753
1754
        $this->assertEquals($childCountBefore - 1, $childCountAfter);
1755
    }
1756
1757
    /**
1758
     * Test for the deleteLocation() method.
1759
     *
1760
     * Related issue: EZP-21904
1761
     *
1762
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1763
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1764
     */
1765
    public function testDeleteContentObjectLastLocation()
1766
    {
1767
        $repository = $this->getRepository();
1768
1769
        /* BEGIN: Use case */
1770
        $contentService = $repository->getContentService();
1771
        $locationService = $repository->getLocationService();
1772
        $contentTypeService = $repository->getContentTypeService();
1773
        $urlAliasService = $repository->getURLAliasService();
1774
1775
        // prepare Content object
1776
        $createStruct = $contentService->newContentCreateStruct(
1777
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1778
            'eng-GB'
1779
        );
1780
        $createStruct->setField('name', 'Test folder');
1781
1782
        // creata Content object
1783
        $content = $contentService->publishVersion(
1784
            $contentService->createContent(
1785
                $createStruct,
1786
                array($locationService->newLocationCreateStruct(2))
1787
            )->versionInfo
1788
        );
1789
1790
        // delete location
1791
        $locationService->deleteLocation(
1792
            $locationService->loadLocation(
1793
                $urlAliasService->lookup('/Test-folder')->destination
1794
            )
1795
        );
1796
1797
        // this should throw a not found exception
1798
        $contentService->loadContent($content->versionInfo->contentInfo->id);
1799
        /* END: Use case*/
1800
    }
1801
1802
    /**
1803
     * Test for the deleteLocation() method.
1804
     *
1805
     * @covers  \eZ\Publish\API\Repository\LocationService::deleteLocation()
1806
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testDeleteLocation
1807
     */
1808
    public function testDeleteLocationDeletesRelatedBookmarks()
1809
    {
1810
        $repository = $this->getRepository();
1811
1812
        $parentLocationId = $this->generateId('location', 43);
1813
        $childLocationId = $this->generateId('location', 53);
1814
1815
        /* BEGIN: Use Case */
1816
        $locationService = $repository->getLocationService();
1817
        $bookmarkService = $repository->getBookmarkService();
1818
1819
        // Load location
1820
        $childLocation = $locationService->loadLocation($childLocationId);
1821
        // Add location to bookmarks
1822
        $bookmarkService->createBookmark($childLocation);
1823
        // Load parent location
1824
        $parentLocation = $locationService->loadLocation($parentLocationId);
1825
        // Delete parent location
1826
        $locationService->deleteLocation($parentLocation);
1827
        /* END: Use Case */
1828
1829
        // Location isn't bookmarked anymore
1830
        foreach ($bookmarkService->loadBookmarks(0, 9999) as $bookmarkedLocation) {
1831
            $this->assertNotEquals($childLocation->id, $bookmarkedLocation->id);
1832
        }
1833
    }
1834
1835
    /**
1836
     * Test for the copySubtree() method.
1837
     *
1838
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1839
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1840
     */
1841
    public function testCopySubtree()
1842
    {
1843
        $repository = $this->getRepository();
1844
1845
        $mediaLocationId = $this->generateId('location', 43);
1846
        $demoDesignLocationId = $this->generateId('location', 56);
1847
        /* BEGIN: Use Case */
1848
        // $mediaLocationId is the ID of the "Media" page location in
1849
        // an eZ Publish demo installation
1850
1851
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1852
        // Publish demo installation
1853
1854
        // Load the location service
1855
        $locationService = $repository->getLocationService();
1856
1857
        // Load location to copy
1858
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1859
1860
        // Load new parent location
1861
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1862
1863
        // Copy location "Media" to "Demo Design"
1864
        $copiedLocation = $locationService->copySubtree(
1865
            $locationToCopy,
1866
            $newParentLocation
1867
        );
1868
        /* END: Use Case */
1869
1870
        $this->assertInstanceOf(
1871
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1872
            $copiedLocation
1873
        );
1874
1875
        $this->assertPropertiesCorrect(
1876
            array(
1877
                'depth' => $newParentLocation->depth + 1,
1878
                'parentLocationId' => $newParentLocation->id,
1879
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $copiedLocation->id) . '/',
1880
            ),
1881
            $copiedLocation
1882
        );
1883
1884
        $this->assertDefaultContentStates($copiedLocation->contentInfo);
1885
    }
1886
1887
    /**
1888
     * Test for the copySubtree() method.
1889
     *
1890
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1891
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1892
     */
1893
    public function testCopySubtreeWithAliases()
1894
    {
1895
        $repository = $this->getRepository();
1896
        $urlAliasService = $repository->getURLAliasService();
1897
1898
        // $mediaLocationId is the ID of the "Media" page location in
1899
        // an eZ Publish demo installation
1900
1901
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1902
        // Publish demo installation
1903
        $mediaLocationId = $this->generateId('location', 43);
1904
        $demoDesignLocationId = $this->generateId('location', 56);
1905
1906
        $locationService = $repository->getLocationService();
1907
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1908
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1909
1910
        $expectedSubItemAliases = [
1911
            '/Design/Plain-site/Media/Multimedia',
1912
            '/Design/Plain-site/Media/Images',
1913
            '/Design/Plain-site/Media/Files',
1914
        ];
1915
1916
        $this->assertAliasesBeforeCopy($urlAliasService, $expectedSubItemAliases);
1917
1918
        // Copy location "Media" to "Design"
1919
        $locationService->copySubtree(
1920
            $locationToCopy,
1921
            $newParentLocation
1922
        );
1923
1924
        $this->assertGeneratedAliases($urlAliasService, $expectedSubItemAliases);
1925
    }
1926
1927
    /**
1928
     * Asserts that given Content has default ContentStates.
1929
     *
1930
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
1931
     */
1932 View Code Duplication
    private function assertDefaultContentStates(ContentInfo $contentInfo)
1933
    {
1934
        $repository = $this->getRepository();
1935
        $objectStateService = $repository->getObjectStateService();
1936
1937
        $objectStateGroups = $objectStateService->loadObjectStateGroups();
1938
1939
        foreach ($objectStateGroups as $objectStateGroup) {
1940
            $contentState = $objectStateService->getContentState($contentInfo, $objectStateGroup);
1941
            foreach ($objectStateService->loadObjectStates($objectStateGroup) as $objectState) {
1942
                // Only check the first object state which is the default one.
1943
                $this->assertEquals(
1944
                    $objectState,
1945
                    $contentState
1946
                );
1947
                break;
1948
            }
1949
        }
1950
    }
1951
1952
    /**
1953
     * Test for the copySubtree() method.
1954
     *
1955
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1956
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
1957
     */
1958
    public function testCopySubtreeUpdatesSubtreeProperties()
1959
    {
1960
        $repository = $this->getRepository();
1961
        $locationService = $repository->getLocationService();
1962
1963
        $locationToCopy = $locationService->loadLocation($this->generateId('location', 43));
1964
1965
        // Load Subtree properties before copy
1966
        $expected = $this->loadSubtreeProperties($locationToCopy);
1967
1968
        $mediaLocationId = $this->generateId('location', 43);
1969
        $demoDesignLocationId = $this->generateId('location', 56);
1970
        /* BEGIN: Use Case */
1971
        // $mediaLocationId is the ID of the "Media" page location in
1972
        // an eZ Publish demo installation
1973
1974
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1975
        // Publish demo installation
1976
1977
        // Load the location service
1978
        $locationService = $repository->getLocationService();
1979
1980
        // Load location to copy
1981
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1982
1983
        // Load new parent location
1984
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1985
1986
        // Copy location "Media" to "Demo Design"
1987
        $copiedLocation = $locationService->copySubtree(
1988
            $locationToCopy,
1989
            $newParentLocation
1990
        );
1991
        /* END: Use Case */
1992
1993
        $beforeIds = array();
1994
        foreach ($expected as $properties) {
1995
            $beforeIds[] = $properties['id'];
1996
        }
1997
1998
        $this->refreshSearch($repository);
1999
2000
        // Load Subtree properties after copy
2001
        $actual = $this->loadSubtreeProperties($copiedLocation);
2002
2003
        $this->assertEquals(count($expected), count($actual));
2004
2005
        foreach ($actual as $properties) {
2006
            $this->assertNotContains($properties['id'], $beforeIds);
2007
            $this->assertStringStartsWith(
2008
                $newParentLocation->pathString . $this->parseId('location', $copiedLocation->id) . '/',
2009
                $properties['pathString']
2010
            );
2011
            $this->assertStringEndsWith(
2012
                '/' . $this->parseId('location', $properties['id']) . '/',
2013
                $properties['pathString']
2014
            );
2015
        }
2016
    }
2017
2018
    /**
2019
     * Test for the copySubtree() method.
2020
     *
2021
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
2022
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
2023
     */
2024
    public function testCopySubtreeIncrementsChildCountOfNewParent()
2025
    {
2026
        $repository = $this->getRepository();
2027
        $locationService = $repository->getLocationService();
2028
2029
        $childCountBefore = $locationService->getLocationChildCount($locationService->loadLocation(56));
2030
2031
        $mediaLocationId = $this->generateId('location', 43);
2032
        $demoDesignLocationId = $this->generateId('location', 56);
2033
        /* BEGIN: Use Case */
2034
        // $mediaLocationId is the ID of the "Media" page location in
2035
        // an eZ Publish demo installation
2036
2037
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2038
        // Publish demo installation
2039
2040
        // Load the location service
2041
        $locationService = $repository->getLocationService();
2042
2043
        // Load location to copy
2044
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
2045
2046
        // Load new parent location
2047
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2048
2049
        // Copy location "Media" to "Demo Design"
2050
        $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...
2051
            $locationToCopy,
2052
            $newParentLocation
2053
        );
2054
        /* END: Use Case */
2055
2056
        $this->refreshSearch($repository);
2057
2058
        $childCountAfter = $locationService->getLocationChildCount($locationService->loadLocation($demoDesignLocationId));
2059
2060
        $this->assertEquals($childCountBefore + 1, $childCountAfter);
2061
    }
2062
2063
    /**
2064
     * Test for the copySubtree() method.
2065
     *
2066
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
2067
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2068
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
2069
     */
2070 View Code Duplication
    public function testCopySubtreeThrowsInvalidArgumentException()
2071
    {
2072
        $repository = $this->getRepository();
2073
2074
        $communityLocationId = $this->generateId('location', 5);
2075
        /* BEGIN: Use Case */
2076
        // $communityLocationId is the ID of the "Community" page location in
2077
        // an eZ Publish demo installation
2078
2079
        // Load the location service
2080
        $locationService = $repository->getLocationService();
2081
2082
        // Load location to copy
2083
        $locationToCopy = $locationService->loadLocation($communityLocationId);
2084
2085
        // Use a child as new parent
2086
        $childLocations = $locationService->loadLocationChildren($locationToCopy)->locations;
2087
        $newParentLocation = end($childLocations);
2088
2089
        // This call will fail with an "InvalidArgumentException", because the
2090
        // new parent is a child location of the subtree to copy.
2091
        $locationService->copySubtree(
2092
            $locationToCopy,
2093
            $newParentLocation
0 ignored issues
show
Security Bug introduced by
It seems like $newParentLocation defined by end($childLocations) on line 2087 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...
2094
        );
2095
        /* END: Use Case */
2096
    }
2097
2098
    /**
2099
     * Test for the moveSubtree() method.
2100
     *
2101
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2102
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
2103
     */
2104
    public function testMoveSubtree()
2105
    {
2106
        $repository = $this->getRepository();
2107
2108
        $mediaLocationId = $this->generateId('location', 43);
2109
        $demoDesignLocationId = $this->generateId('location', 56);
2110
        /* BEGIN: Use Case */
2111
        // $mediaLocationId is the ID of the "Media" page location in
2112
        // an eZ Publish demo installation
2113
2114
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2115
        // Publish demo installation
2116
2117
        // Load the location service
2118
        $locationService = $repository->getLocationService();
2119
2120
        // Load location to move
2121
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2122
2123
        // Load new parent location
2124
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2125
2126
        // Move location from "Home" to "Demo Design"
2127
        $locationService->moveSubtree(
2128
            $locationToMove,
2129
            $newParentLocation
2130
        );
2131
2132
        // Load moved location
2133
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2134
        /* END: Use Case */
2135
2136
        $this->assertPropertiesCorrect(
2137
            array(
2138
                'hidden' => false,
2139
                'invisible' => false,
2140
                'depth' => $newParentLocation->depth + 1,
2141
                'parentLocationId' => $newParentLocation->id,
2142
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $movedLocation->id) . '/',
2143
            ),
2144
            $movedLocation
2145
        );
2146
    }
2147
2148
    /**
2149
     * Test for the moveSubtree() method.
2150
     *
2151
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2152
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2153
     */
2154
    public function testMoveSubtreeHidden()
2155
    {
2156
        $repository = $this->getRepository();
2157
2158
        $mediaLocationId = $this->generateId('location', 43);
2159
        $demoDesignLocationId = $this->generateId('location', 56);
2160
        /* BEGIN: Use Case */
2161
        // $mediaLocationId is the ID of the "Media" page location in
2162
        // an eZ Publish demo installation
2163
2164
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2165
        // Publish demo installation
2166
2167
        // Load the location service
2168
        $locationService = $repository->getLocationService();
2169
2170
        // Load location to move
2171
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2172
2173
        // Load new parent location
2174
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2175
2176
        // Hide the target location before we move
2177
        $newParentLocation = $locationService->hideLocation($newParentLocation);
2178
2179
        // Move location from "Home" to "Demo Design"
2180
        $locationService->moveSubtree(
2181
            $locationToMove,
2182
            $newParentLocation
2183
        );
2184
2185
        // Load moved location
2186
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2187
        /* END: Use Case */
2188
2189
        $this->assertPropertiesCorrect(
2190
            array(
2191
                'hidden' => false,
2192
                'invisible' => true,
2193
                'depth' => $newParentLocation->depth + 1,
2194
                'parentLocationId' => $newParentLocation->id,
2195
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $movedLocation->id) . '/',
2196
            ),
2197
            $movedLocation
2198
        );
2199
    }
2200
2201
    /**
2202
     * Test for the moveSubtree() method.
2203
     *
2204
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2205
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2206
     */
2207
    public function testMoveSubtreeUpdatesSubtreeProperties()
2208
    {
2209
        $repository = $this->getRepository();
2210
        $locationService = $repository->getLocationService();
2211
2212
        $locationToMove = $locationService->loadLocation($this->generateId('location', 43));
2213
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2214
2215
        // Load Subtree properties before move
2216
        $expected = $this->loadSubtreeProperties($locationToMove);
2217
        foreach ($expected as $id => $properties) {
2218
            $expected[$id]['depth'] = $properties['depth'] + 2;
2219
            $expected[$id]['pathString'] = str_replace(
2220
                $locationToMove->pathString,
2221
                $newParentLocation->pathString . $this->parseId('location', $locationToMove->id) . '/',
2222
                $properties['pathString']
2223
            );
2224
        }
2225
2226
        $mediaLocationId = $this->generateId('location', 43);
2227
        $demoDesignLocationId = $this->generateId('location', 56);
2228
        /* BEGIN: Use Case */
2229
        // $mediaLocationId is the ID of the "Media" page location in
2230
        // an eZ Publish demo installation
2231
2232
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2233
        // Publish demo installation
2234
2235
        // Load the location service
2236
        $locationService = $repository->getLocationService();
2237
2238
        // Load location to move
2239
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2240
2241
        // Load new parent location
2242
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2243
2244
        // Move location from "Home" to "Demo Design"
2245
        $locationService->moveSubtree(
2246
            $locationToMove,
2247
            $newParentLocation
2248
        );
2249
2250
        // Load moved location
2251
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2252
        /* END: Use Case */
2253
2254
        $this->refreshSearch($repository);
2255
2256
        // Load Subtree properties after move
2257
        $actual = $this->loadSubtreeProperties($movedLocation);
2258
2259
        $this->assertEquals($expected, $actual);
2260
    }
2261
2262
    /**
2263
     * Test for the moveSubtree() method.
2264
     *
2265
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2266
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtreeUpdatesSubtreeProperties
2267
     */
2268
    public function testMoveSubtreeUpdatesSubtreePropertiesHidden()
2269
    {
2270
        $repository = $this->getRepository();
2271
        $locationService = $repository->getLocationService();
2272
2273
        $locationToMove = $locationService->loadLocation($this->generateId('location', 43));
2274
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2275
2276
        // Hide the target location before we move
2277
        $newParentLocation = $locationService->hideLocation($newParentLocation);
2278
2279
        // Load Subtree properties before move
2280
        $expected = $this->loadSubtreeProperties($locationToMove);
2281
        foreach ($expected as $id => $properties) {
2282
            $expected[$id]['invisible'] = true;
2283
            $expected[$id]['depth'] = $properties['depth'] + 2;
2284
            $expected[$id]['pathString'] = str_replace(
2285
                $locationToMove->pathString,
2286
                $newParentLocation->pathString . $this->parseId('location', $locationToMove->id) . '/',
2287
                $properties['pathString']
2288
            );
2289
        }
2290
2291
        $mediaLocationId = $this->generateId('location', 43);
2292
        $demoDesignLocationId = $this->generateId('location', 56);
2293
        /* BEGIN: Use Case */
2294
        // $mediaLocationId is the ID of the "Media" page location in
2295
        // an eZ Publish demo installation
2296
2297
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2298
        // Publish demo installation
2299
2300
        // Load the location service
2301
        $locationService = $repository->getLocationService();
2302
2303
        // Load location to move
2304
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2305
2306
        // Load new parent location
2307
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2308
2309
        // Move location from "Home" to "Demo Design"
2310
        $locationService->moveSubtree(
2311
            $locationToMove,
2312
            $newParentLocation
2313
        );
2314
2315
        // Load moved location
2316
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2317
        /* END: Use Case */
2318
2319
        $this->refreshSearch($repository);
2320
2321
        // Load Subtree properties after move
2322
        $actual = $this->loadSubtreeProperties($movedLocation);
2323
2324
        $this->assertEquals($expected, $actual);
2325
    }
2326
2327
    /**
2328
     * Test for the moveSubtree() method.
2329
     *
2330
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2331
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2332
     */
2333 View Code Duplication
    public function testMoveSubtreeIncrementsChildCountOfNewParent()
2334
    {
2335
        $repository = $this->getRepository();
2336
        $locationService = $repository->getLocationService();
2337
2338
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2339
2340
        // Load expected properties before move
2341
        $expected = $this->loadLocationProperties($newParentLocation);
2342
        $childCountBefore = $locationService->getLocationChildCount($newParentLocation);
2343
2344
        $mediaLocationId = $this->generateId('location', 43);
2345
        $demoDesignLocationId = $this->generateId('location', 56);
2346
        /* BEGIN: Use Case */
2347
        // $mediaLocationId is the ID of the "Media" page location in
2348
        // an eZ Publish demo installation
2349
2350
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2351
        // Publish demo installation
2352
2353
        // Load the location service
2354
        $locationService = $repository->getLocationService();
2355
2356
        // Load location to move
2357
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2358
2359
        // Load new parent location
2360
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2361
2362
        // Move location from "Home" to "Demo Design"
2363
        $locationService->moveSubtree(
2364
            $locationToMove,
2365
            $newParentLocation
2366
        );
2367
2368
        // Load moved location
2369
        $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...
2370
2371
        // Reload new parent location
2372
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2373
        /* END: Use Case */
2374
2375
        $this->refreshSearch($repository);
2376
2377
        // Load Subtree properties after move
2378
        $actual = $this->loadLocationProperties($newParentLocation);
2379
        $childCountAfter = $locationService->getLocationChildCount($newParentLocation);
2380
2381
        $this->assertEquals($expected, $actual);
2382
        $this->assertEquals($childCountBefore + 1, $childCountAfter);
2383
    }
2384
2385
    /**
2386
     * Test for the moveSubtree() method.
2387
     *
2388
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2389
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2390
     */
2391 View Code Duplication
    public function testMoveSubtreeDecrementsChildCountOfOldParent()
2392
    {
2393
        $repository = $this->getRepository();
2394
        $locationService = $repository->getLocationService();
2395
2396
        $oldParentLocation = $locationService->loadLocation($this->generateId('location', 1));
2397
2398
        // Load expected properties before move
2399
        $expected = $this->loadLocationProperties($oldParentLocation);
2400
        $childCountBefore = $locationService->getLocationChildCount($oldParentLocation);
2401
2402
        $mediaLocationId = $this->generateId('location', 43);
2403
        $demoDesignLocationId = $this->generateId('location', 56);
2404
        /* BEGIN: Use Case */
2405
        // $mediaLocationId is the ID of the "Media" page location in
2406
        // an eZ Publish demo installation
2407
2408
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2409
        // Publish demo installation
2410
2411
        // Load the location service
2412
        $locationService = $repository->getLocationService();
2413
2414
        // Load location to move
2415
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2416
2417
        // Get the location id of the old parent
2418
        $oldParentLocationId = $locationToMove->parentLocationId;
2419
2420
        // Load new parent location
2421
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2422
2423
        // Move location from "Home" to "Demo Design"
2424
        $locationService->moveSubtree(
2425
            $locationToMove,
2426
            $newParentLocation
2427
        );
2428
2429
        // Reload old parent location
2430
        $oldParentLocation = $locationService->loadLocation($oldParentLocationId);
2431
        /* END: Use Case */
2432
2433
        $this->refreshSearch($repository);
2434
2435
        // Load Subtree properties after move
2436
        $actual = $this->loadLocationProperties($oldParentLocation);
2437
        $childCountAfter = $locationService->getLocationChildCount($oldParentLocation);
2438
2439
        $this->assertEquals($expected, $actual);
2440
        $this->assertEquals($childCountBefore - 1, $childCountAfter);
2441
    }
2442
2443
    /**
2444
     * Test for the moveSubtree() method.
2445
     *
2446
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2447
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2448
     */
2449 View Code Duplication
    public function testMoveSubtreeThrowsInvalidArgumentException()
2450
    {
2451
        $repository = $this->getRepository();
2452
        $mediaLocationId = $this->generateId('location', 43);
2453
        $multimediaLocationId = $this->generateId('location', 53);
2454
2455
        /* BEGIN: Use Case */
2456
        // $mediaLocationId is the ID of the "Media" page location in
2457
        // an eZ Publish demo installation
2458
2459
        // $multimediaLocationId is the ID of the "Multimedia" page location in an eZ
2460
        // Publish demo installation
2461
2462
        // Load the location service
2463
        $locationService = $repository->getLocationService();
2464
2465
        // Load location to move
2466
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2467
2468
        // Load new parent location
2469
        $newParentLocation = $locationService->loadLocation($multimediaLocationId);
2470
2471
        // Throws an exception because new parent location is placed below location to move
2472
        $locationService->moveSubtree(
2473
            $locationToMove,
2474
            $newParentLocation
2475
        );
2476
        /* END: Use Case */
2477
    }
2478
2479
    /**
2480
     * Loads properties from all locations in the $location's subtree.
2481
     *
2482
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
2483
     * @param array $properties
2484
     *
2485
     * @return array
2486
     */
2487
    private function loadSubtreeProperties(Location $location, array $properties = array())
2488
    {
2489
        $locationService = $this->getRepository()->getLocationService();
2490
2491
        foreach ($locationService->loadLocationChildren($location)->locations as $childLocation) {
2492
            $properties[] = $this->loadLocationProperties($childLocation);
2493
2494
            $properties = $this->loadSubtreeProperties($childLocation, $properties);
2495
        }
2496
2497
        return $properties;
2498
    }
2499
2500
    /**
2501
     * Loads assertable properties from the given location.
2502
     *
2503
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
2504
     * @param mixed[] $overwrite
2505
     *
2506
     * @return array
2507
     */
2508
    private function loadLocationProperties(Location $location, array $overwrite = array())
2509
    {
2510
        return array_merge(
2511
            array(
2512
                'id' => $location->id,
2513
                'depth' => $location->depth,
2514
                'parentLocationId' => $location->parentLocationId,
2515
                'pathString' => $location->pathString,
2516
                'remoteId' => $location->remoteId,
2517
                'hidden' => $location->hidden,
2518
                'invisible' => $location->invisible,
2519
                'priority' => $location->priority,
2520
                'sortField' => $location->sortField,
2521
                'sortOrder' => $location->sortOrder,
2522
            ),
2523
            $overwrite
2524
        );
2525
    }
2526
2527
    /**
2528
     * Assert generated aliases to expected alias return.
2529
     *
2530
     * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
2531
     * @param array $expectedAliases
2532
     */
2533
    protected function assertGeneratedAliases($urlAliasService, array $expectedAliases)
2534
    {
2535
        foreach ($expectedAliases as $expectedAlias) {
2536
            $urlAlias = $urlAliasService->lookup($expectedAlias);
2537
            $this->assertPropertiesCorrect(['type' => 0], $urlAlias);
2538
        }
2539
    }
2540
2541
    /**
2542
     * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
2543
     * @param array $expectedSubItemAliases
2544
     */
2545
    private function assertAliasesBeforeCopy($urlAliasService, array $expectedSubItemAliases)
2546
    {
2547
        foreach ($expectedSubItemAliases as $aliasUrl) {
2548
            try {
2549
                $urlAliasService->lookup($aliasUrl);
2550
                $this->fail('We didn\'t expect to find alias, but it was found');
2551
            } catch (\Exception $e) {
2552
                $this->assertTrue(true); // OK - alias was not found
2553
            }
2554
        }
2555
    }
2556
2557
    /**
2558
     * Create and publish Content with the given parent Location.
2559
     *
2560
     * @param string $contentName
2561
     * @param int $parentLocationId
2562
     *
2563
     * @return \eZ\Publish\API\Repository\Values\Content\Content published Content
2564
     */
2565 View Code Duplication
    private function publishContentWithParentLocation($contentName, $parentLocationId)
2566
    {
2567
        $repository = $this->getRepository(false);
2568
        $locationService = $repository->getLocationService();
2569
2570
        $contentService = $repository->getContentService();
2571
        $contentTypeService = $repository->getContentTypeService();
2572
2573
        $contentCreateStruct = $contentService->newContentCreateStruct(
2574
            $contentTypeService->loadContentTypeByIdentifier('folder'),
2575
            'eng-US'
2576
        );
2577
        $contentCreateStruct->setField('name', $contentName);
2578
        $contentDraft = $contentService->createContent(
2579
            $contentCreateStruct,
2580
            [
2581
                $locationService->newLocationCreateStruct($parentLocationId),
2582
            ]
2583
        );
2584
2585
        return $contentService->publishVersion($contentDraft->versionInfo);
2586
    }
2587
}
2588