Completed
Push — EZEE-3159 ( 5aed86...7e7924 )
by
unknown
40:23
created

testFindTrashItemsSubtreeLimitation()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 56
rs 8.9599
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Publish\API\Repository\Tests;
8
9
use eZ\Publish\API\Repository\Repository;
10
use eZ\Publish\API\Repository\URLAliasService;
11
use eZ\Publish\API\Repository\Values\Content\Content;
12
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
13
use eZ\Publish\API\Repository\Values\Content\Location as APILocation;
14
use eZ\Publish\API\Repository\Values\Content\LocationCreateStruct;
15
use eZ\Publish\API\Repository\Values\Content\Query;
16
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
17
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
18
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
19
use eZ\Publish\API\Repository\Values\Content\Trash\SearchResult;
20
use eZ\Publish\API\Repository\Values\Content\TrashItem as APITrashItem;
21
use eZ\Publish\API\Repository\Values\User\Limitation\SubtreeLimitation;
22
use eZ\Publish\Core\Repository\Values\Content\TrashItem;
23
use eZ\Publish\Core\Repository\Values\Content\Location;
24
use DateTime;
25
26
/**
27
 * Test case for operations in the TrashService using in memory storage.
28
 *
29
 * @see eZ\Publish\API\Repository\TrashService
30
 * @group integration
31
 * @group trash
32
 */
33
class TrashServiceTest extends BaseTrashServiceTest
34
{
35
    /**
36
     * Test for the trash() method.
37
     *
38
     * @see \eZ\Publish\API\Repository\TrashService::trash()
39
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationByRemoteId
40
     */
41
    public function testTrash()
42
    {
43
        /* BEGIN: Use Case */
44
        $trashItem = $this->createTrashItem();
45
        /* END: Use Case */
46
47
        $this->assertInstanceOf(
48
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\TrashItem',
49
            $trashItem
50
        );
51
    }
52
53
    /**
54
     * Test for the trash() method.
55
     *
56
     * @see \eZ\Publish\API\Repository\TrashService::trash()
57
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
58
     */
59
    public function testTrashSetsExpectedTrashItemProperties()
60
    {
61
        $repository = $this->getRepository();
62
63
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
64
65
        // Load the location that will be trashed
66
        $location = $repository->getLocationService()
67
            ->loadLocationByRemoteId($mediaRemoteId);
68
69
        $expected = [
70
            'id' => $location->id,
71
            'depth' => $location->depth,
72
            'hidden' => $location->hidden,
73
            'invisible' => $location->invisible,
74
            'parentLocationId' => $location->parentLocationId,
75
            'pathString' => $location->pathString,
76
            'priority' => $location->priority,
77
            'remoteId' => $location->remoteId,
78
            'sortField' => $location->sortField,
79
            'sortOrder' => $location->sortOrder,
80
        ];
81
82
        $trashItem = $this->createTrashItem();
83
84
        $this->assertPropertiesCorrect($expected, $trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 82 can be null; however, eZ\Publish\API\Repositor...sertPropertiesCorrect() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
85
    }
86
87
    /**
88
     * Test for the trash() method.
89
     *
90
     * @see \eZ\Publish\API\Repository\TrashService::trash()
91
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
92
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
93
     */
94
    public function testTrashRemovesLocationFromMainStorage()
95
    {
96
        $repository = $this->getRepository();
97
98
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
99
100
        /* BEGIN: Use Case */
101
        $this->createTrashItem();
102
103
        // Load the location service
104
        $locationService = $repository->getLocationService();
105
106
        // This call will fail with a "NotFoundException", because the media
107
        // location was marked as trashed in the main storage
108
        $locationService->loadLocationByRemoteId($mediaRemoteId);
109
        /* END: Use Case */
110
    }
111
112
    /**
113
     * Test for the trash() method.
114
     *
115
     * @see \eZ\Publish\API\Repository\TrashService::trash()
116
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
117
     */
118
    public function testTrashRemovesChildLocationsFromMainStorage()
119
    {
120
        $repository = $this->getRepository();
121
122
        /* BEGIN: Use Case */
123
        $remoteIds = $this->createRemoteIdList();
124
125
        $this->createTrashItem();
126
127
        // All invocations to loadLocationByRemoteId() to one of the above
128
        // collected remoteIds will return in an "NotFoundException"
129
        /* END: Use Case */
130
131
        $locationService = $repository->getLocationService();
132
        foreach ($remoteIds as $remoteId) {
133
            try {
134
                $locationService->loadLocationByRemoteId($remoteId);
135
                $this->fail("Location '{$remoteId}' should exist.'");
136
            } catch (NotFoundException $e) {
137
                // echo $e->getFile(), ' +', $e->getLine(), PHP_EOL;
138
            }
139
        }
140
141
        $this->assertGreaterThan(
142
            0,
143
            count($remoteIds),
144
            "There should be at least one 'Community' child location."
145
        );
146
    }
147
148
    /**
149
     * Test for the trash() method.
150
     *
151
     * @see \eZ\Publish\API\Repository\TrashService::trash()
152
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
153
     */
154 View Code Duplication
    public function testTrashDecrementsChildCountOnParentLocation()
155
    {
156
        $repository = $this->getRepository();
157
        $locationService = $repository->getLocationService();
158
159
        $baseLocationId = $this->generateId('location', 1);
160
161
        $location = $locationService->loadLocation($baseLocationId);
162
163
        $childCount = $locationService->getLocationChildCount($location);
164
165
        $this->createTrashItem();
166
167
        $this->refreshSearch($repository);
168
169
        $this->assertEquals(
170
            $childCount - 1,
171
            $locationService->getLocationChildCount($location)
172
        );
173
    }
174
175
    /**
176
     * Test sending a location to trash updates Content mainLocation.
177
     *
178
     * @covers \eZ\Publish\API\Repository\TrashService::trash
179
     */
180
    public function testTrashUpdatesMainLocation()
181
    {
182
        $repository = $this->getRepository();
183
        $contentService = $repository->getContentService();
184
        $locationService = $repository->getLocationService();
185
        $trashService = $repository->getTrashService();
186
187
        $contentInfo = $contentService->loadContentInfo(42);
188
189
        // Create additional location that will become new main location
190
        $location = $locationService->createLocation(
191
            $contentInfo,
192
            new LocationCreateStruct(['parentLocationId' => 2])
193
        );
194
195
        $trashService->trash(
196
            $locationService->loadLocation($contentInfo->mainLocationId)
197
        );
198
199
        self::assertEquals(
200
            $location->id,
201
            $contentService->loadContentInfo(42)->mainLocationId
202
        );
203
    }
204
205
    /**
206
     * Test sending a location to trash.
207
     *
208
     * @covers \eZ\Publish\API\Repository\TrashService::trash
209
     */
210 View Code Duplication
    public function testTrashReturnsNull()
211
    {
212
        $repository = $this->getRepository();
213
        $contentService = $repository->getContentService();
214
        $locationService = $repository->getLocationService();
215
        $trashService = $repository->getTrashService();
216
217
        // Create additional location to trash
218
        $location = $locationService->createLocation(
219
            $contentService->loadContentInfo(42),
220
            new LocationCreateStruct(['parentLocationId' => 2])
221
        );
222
223
        $trashItem = $trashService->trash($location);
224
225
        self::assertNull($trashItem);
226
    }
227
228
    /**
229
     * Test for the loadTrashItem() method.
230
     *
231
     * @covers \eZ\Publish\API\Repository\TrashService::loadTrashItem
232
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
233
     */
234
    public function testLoadTrashItem()
235
    {
236
        $repository = $this->getRepository();
237
        $trashService = $repository->getTrashService();
238
239
        /* BEGIN: Use Case */
240
        $trashItem = $this->createTrashItem();
241
242
        // Reload the trash item
243
        $trashItemReloaded = $trashService->loadTrashItem($trashItem->id);
244
        /* END: Use Case */
245
246
        $this->assertInstanceOf(
247
            APITrashItem::class,
248
            $trashItemReloaded
249
        );
250
251
        $this->assertEquals(
252
            $trashItem->pathString,
253
            $trashItemReloaded->pathString
254
        );
255
256
        $this->assertEquals(
257
            $trashItem,
258
            $trashItemReloaded
259
        );
260
261
        $this->assertInstanceOf(
262
            DateTime::class,
263
            $trashItemReloaded->trashed
264
        );
265
266
        $this->assertEquals(
267
            $trashItem->trashed->getTimestamp(),
268
            $trashItemReloaded->trashed->getTimestamp()
269
        );
270
271
        $this->assertGreaterThan(
272
            0,
273
            $trashItemReloaded->trashed->getTimestamp()
274
        );
275
276
        $this->assertInstanceOf(
277
            Content::class,
278
            $content = $trashItemReloaded->getContent()
279
        );
280
        $this->assertEquals($trashItem->contentId, $content->contentInfo->id);
281
    }
282
283
    /**
284
     * Test for the loadTrashItem() method.
285
     *
286
     * @see \eZ\Publish\API\Repository\TrashService::loadTrashItem()
287
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
288
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testLoadTrashItem
289
     */
290
    public function testLoadTrashItemThrowsNotFoundException()
291
    {
292
        $repository = $this->getRepository();
293
294
        $nonExistingTrashId = $this->generateId('trash', 2342);
295
        /* BEGIN: Use Case */
296
        $trashService = $repository->getTrashService();
297
298
        // This call will fail with a "NotFoundException", because no trash item
299
        // with the ID 1342 should exist in an eZ Publish demo installation
300
        $trashService->loadTrashItem($nonExistingTrashId);
301
        /* END: Use Case */
302
    }
303
304
    /**
305
     * Test for the recover() method.
306
     *
307
     * @covers \eZ\Publish\API\Repository\TrashService::recover
308
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
309
     */
310
    public function testRecover()
311
    {
312
        $repository = $this->getRepository();
313
        $trashService = $repository->getTrashService();
314
        $locationService = $repository->getLocationService();
315
316
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
317
318
        /* BEGIN: Use Case */
319
        $trashItem = $this->createTrashItem();
320
321
        // Recover the trashed item
322
        $location = $trashService->recover($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 319 can be null; however, eZ\Publish\API\Repository\TrashService::recover() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
323
324
        // Load the recovered location
325
        $locationReloaded = $locationService->loadLocationByRemoteId(
326
            $mediaRemoteId
327
        );
328
        /* END: Use Case */
329
330
        $this->assertInstanceOf(
331
            APILocation::class,
332
            $location
333
        );
334
335
        $this->assertEquals(
336
            $location,
337
            $locationReloaded
338
        );
339
340
        try {
341
            $trashService->loadTrashItem($trashItem->id);
342
            $this->fail('Trash item was not removed after being recovered.');
343
        } catch (NotFoundException $e) {
344
            // All well
345
        }
346
    }
347
348
    /**
349
     * Test recovering a non existing trash item results in a NotFoundException.
350
     *
351
     * @covers \eZ\Publish\API\Repository\TrashService::recover
352
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
353
     */
354
    public function testRecoverThrowsNotFoundExceptionForNonExistingTrashItem()
355
    {
356
        $repository = $this->getRepository();
357
        $trashService = $repository->getTrashService();
358
359
        $trashService->recover(
360
            $this->getTrashItemDouble(
361
                12364,
362
                12345,
363
                12363
364
            )
365
        );
366
    }
367
368
    /**
369
     * Test for the trash() method.
370
     *
371
     * @see \eZ\Publish\API\Repository\TrashService::recover()
372
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
373
     *
374
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
375
     */
376
    public function testNotFoundAliasAfterRemoveIt()
377
    {
378
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
379
380
        $repository = $this->getRepository();
381
        $trashService = $repository->getTrashService();
382
        $urlAliasService = $repository->getURLAliasService();
383
        $locationService = $repository->getLocationService();
384
385
        // Double ->lookup() call because there where issue that one call was not enough to spot bug
386
        $urlAliasService->lookup('/Media');
387
        $urlAliasService->lookup('/Media');
388
389
        $mediaLocation = $locationService->loadLocationByRemoteId($mediaRemoteId);
390
        $trashService->trash($mediaLocation);
391
392
        $urlAliasService->lookup('/Media');
393
    }
394
395
    /**
396
     * Test for the recover() method.
397
     *
398
     * @see \eZ\Publish\API\Repository\TrashService::recover()
399
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
400
     */
401
    public function testAliasesForRemovedItems()
402
    {
403
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
404
405
        $repository = $this->getRepository();
406
        $trashService = $repository->getTrashService();
407
        $urlAliasService = $repository->getURLAliasService();
408
        $locationService = $repository->getLocationService();
409
410
        // Double ->lookup() call because there where issue that one call was not enough to spot bug
411
        $urlAliasService->lookup('/Media');
412
        $trashedLocationAlias = $urlAliasService->lookup('/Media');
413
414
        $mediaLocation = $locationService->loadLocationByRemoteId($mediaRemoteId);
415
        $trashItem = $trashService->trash($mediaLocation);
416
        $this->assertAliasNotExists($urlAliasService, '/Media');
417
418
        $this->createNewContentInPlaceTrashedOne($repository, $mediaLocation->parentLocationId);
419
420
        $createdLocationAlias = $urlAliasService->lookup('/Media');
421
422
        $this->assertNotEquals(
423
            $trashedLocationAlias->destination,
424
            $createdLocationAlias->destination,
425
            'Destination for /media url should changed'
426
        );
427
428
        $recoveredLocation = $trashService->recover($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $trashService->trash($mediaLocation) on line 415 can be null; however, eZ\Publish\API\Repository\TrashService::recover() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
429
        $recoveredLocationAlias = $urlAliasService->lookup('/Media2');
430
        $recoveredLocationAliasReverse = $urlAliasService->reverseLookup($recoveredLocation);
431
432
        $this->assertEquals($recoveredLocationAlias->destination, $recoveredLocationAliasReverse->destination);
433
434
        $this->assertNotEquals($recoveredLocationAliasReverse->destination, $trashedLocationAlias->destination);
435
        $this->assertNotEquals($recoveredLocationAliasReverse->destination, $createdLocationAlias->destination);
436
    }
437
438
    /**
439
     * Test for the recover() method.
440
     *
441
     * @see \eZ\Publish\API\Repository\TrashService::recover()
442
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testRecover
443
     */
444
    public function testRecoverDoesNotRestoreChildLocations()
445
    {
446
        $repository = $this->getRepository();
447
        $trashService = $repository->getTrashService();
448
        $locationService = $repository->getLocationService();
449
450
        $remoteIds = $this->createRemoteIdList();
451
452
        // Unset remote ID of actually restored location
453
        unset($remoteIds[array_search('3f6d92f8044aed134f32153517850f5a', $remoteIds)]);
454
455
        $trashItem = $this->createTrashItem();
456
457
        $trashService->recover($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 455 can be null; however, eZ\Publish\API\Repository\TrashService::recover() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
458
459
        $this->assertGreaterThan(
460
            0,
461
            count($remoteIds),
462
            "There should be at least one 'Community' child location."
463
        );
464
465
        // None of the child locations will be available again
466
        foreach ($remoteIds as $remoteId) {
467
            try {
468
                $locationService->loadLocationByRemoteId($remoteId);
469
                $this->fail(
470
                    sprintf(
471
                        'Location with remote ID "%s" unexpectedly restored.',
472
                        $remoteId
473
                    )
474
                );
475
            } catch (NotFoundException $e) {
476
                // All well
477
            }
478
        }
479
480
        try {
481
            $trashService->loadTrashItem($trashItem->id);
482
            $this->fail('Trash item was not removed after being recovered.');
483
        } catch (NotFoundException $e) {
484
            // All well
485
        }
486
    }
487
488
    /**
489
     * Test for the recover() method.
490
     *
491
     * @see \eZ\Publish\API\Repository\TrashService::recover($trashItem, $newParentLocation)
492
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testRecover
493
     *
494
     * @todo Fix naming
495
     */
496
    public function testRecoverWithLocationCreateStructParameter()
497
    {
498
        $repository = $this->getRepository();
499
        $trashService = $repository->getTrashService();
500
        $locationService = $repository->getLocationService();
501
502
        $homeLocationId = $this->generateId('location', 2);
503
        /* BEGIN: Use Case */
504
        // $homeLocationId is the ID of the "Home" location in an eZ Publish
505
        // demo installation
506
507
        $trashItem = $this->createTrashItem();
508
509
        // Get the new parent location
510
        $newParentLocation = $locationService->loadLocation($homeLocationId);
511
512
        // Recover location with new location
513
        $location = $trashService->recover($trashItem, $newParentLocation);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 507 can be null; however, eZ\Publish\API\Repository\TrashService::recover() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
514
        /* END: Use Case */
515
516
        $this->assertPropertiesCorrect(
517
            [
518
                'remoteId' => $trashItem->remoteId,
519
                'parentLocationId' => $homeLocationId,
520
                // Not the full sub tree is restored
521
                'depth' => $newParentLocation->depth + 1,
522
                'hidden' => false,
523
                'invisible' => $trashItem->invisible,
524
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $location->id) . '/',
525
                'priority' => 0,
526
                'sortField' => APILocation::SORT_FIELD_NAME,
527
                'sortOrder' => APILocation::SORT_ORDER_ASC,
528
            ],
529
            $location
530
        );
531
532
        try {
533
            $trashService->loadTrashItem($trashItem->id);
534
            $this->fail('Trash item was not removed after being recovered.');
535
        } catch (NotFoundException $e) {
536
            // All well
537
        }
538
    }
539
540
    /**
541
     * Test for the recover() method.
542
     *
543
     * @see \eZ\Publish\API\Repository\TrashService::recover($trashItem)
544
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testRecover
545
     */
546
    public function testRecoverIncrementsChildCountOnOriginalParent()
547
    {
548
        $repository = $this->getRepository();
549
        $trashService = $repository->getTrashService();
550
        $locationService = $repository->getLocationService();
551
552
        $location = $locationService->loadLocation($this->generateId('location', 1));
553
554
        $trashItem = $this->createTrashItem();
555
556
        $this->refreshSearch($repository);
557
558
        /* BEGIN: Use Case */
559
        $childCount = $locationService->getLocationChildCount($location);
560
561
        // Recover location with new location
562
        $trashService->recover($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 554 can be null; however, eZ\Publish\API\Repository\TrashService::recover() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
563
        /* END: Use Case */
564
565
        $this->refreshSearch($repository);
566
567
        $this->assertEquals(
568
            $childCount + 1,
569
            $locationService->getLocationChildCount($location)
570
        );
571
572
        try {
573
            $trashService->loadTrashItem($trashItem->id);
574
            $this->fail('Trash item was not removed after being recovered.');
575
        } catch (NotFoundException $e) {
576
            // All well
577
        }
578
    }
579
580
    /**
581
     * Test for the recover() method.
582
     *
583
     * @see \eZ\Publish\API\Repository\TrashService::recover($trashItem, $newParentLocation)
584
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testRecoverWithLocationCreateStructParameter
585
     */
586
    public function testRecoverWithLocationCreateStructParameterIncrementsChildCountOnNewParent()
587
    {
588
        $repository = $this->getRepository();
589
        $trashService = $repository->getTrashService();
590
        $locationService = $repository->getLocationService();
591
592
        $homeLocationId = $this->generateId('location', 2);
593
594
        $location = $locationService->loadLocation($homeLocationId);
595
596
        $childCount = $locationService->getLocationChildCount($location);
597
598
        /* BEGIN: Use Case */
599
        // $homeLocationId is the ID of the "Home" location in an eZ Publish
600
        // demo installation
601
602
        $trashItem = $this->createTrashItem();
603
604
        // Get the new parent location
605
        $newParentLocation = $locationService->loadLocation($homeLocationId);
606
607
        // Recover location with new location
608
        $trashService->recover($trashItem, $newParentLocation);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 602 can be null; however, eZ\Publish\API\Repository\TrashService::recover() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
609
        /* END: Use Case */
610
611
        $this->refreshSearch($repository);
612
613
        $this->assertEquals(
614
            $childCount + 1,
615
            $locationService->getLocationChildCount($location)
616
        );
617
618
        try {
619
            $trashService->loadTrashItem($trashItem->id);
620
            $this->fail('Trash item was not removed after being recovered.');
621
        } catch (NotFoundException $e) {
622
            // All well
623
        }
624
    }
625
626
    /**
627
     * Test recovering a location from trash to non existing location.
628
     *
629
     * @covers \eZ\Publish\API\Repository\TrashService::recover
630
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
631
     */
632 View Code Duplication
    public function testRecoverToNonExistingLocation()
633
    {
634
        $repository = $this->getRepository();
635
        $trashService = $repository->getTrashService();
636
        $locationService = $repository->getLocationService();
637
638
        $location = $locationService->loadLocation(44);
639
        $trashItem = $trashService->trash($location);
640
641
        $newParentLocation = new Location(
642
            [
643
                'id' => 123456,
644
                'parentLocationId' => 123455,
645
            ]
646
        );
647
        $trashService->recover($trashItem, $newParentLocation);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $trashService->trash($location) on line 639 can be null; however, eZ\Publish\API\Repository\TrashService::recover() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
648
    }
649
650
    /**
651
     * Test for the findTrashItems() method.
652
     *
653
     * @see \eZ\Publish\API\Repository\TrashService::findTrashItems()
654
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
655
     */
656
    public function testFindTrashItems()
657
    {
658
        $repository = $this->getRepository();
659
        $trashService = $repository->getTrashService();
660
661
        /* BEGIN: Use Case */
662
        $this->createTrashItem();
663
664
        // Create a search query for all trashed items
665
        $query = new Query();
666
        $query->filter = new Criterion\LogicalAnd(
667
            [
668
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
669
            ]
670
        );
671
672
        // Load all trashed locations
673
        $searchResult = $trashService->findTrashItems($query);
674
        /* END: Use Case */
675
676
        $this->assertInstanceOf(
677
            SearchResult::class,
678
            $searchResult
679
        );
680
681
        // 4 trashed locations from the sub tree
682
        $this->assertEquals(4, $searchResult->count);
683
        $this->assertEquals(4, $searchResult->totalCount);
684
    }
685
686
    /**
687
     * @covers  \eZ\Publish\API\Repository\TrashService::findTrashItems
688
     *
689
     * @throws \ErrorException
690
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
691
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
692
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
693
     */
694
    public function testFindTrashItemsSortedByDateTrashed(): void
695
    {
696
        $repository = $this->getRepository();
697
        $trashService = $repository->getTrashService();
698
        $locationService = $repository->getLocationService();
699
700
        $folder1 = $this->createFolder(['eng-GB' => 'Folder1'], 2);
701
        $folder2 = $this->createFolder(['eng-GB' => 'Folder2'], 2);
702
703
        $firstTrashedItem = $trashService->trash(
704
            $locationService->loadLocation($folder1->contentInfo->mainLocationId)
705
        );
706
        $this->updateTrashedDate($firstTrashedItem->id, \time() - 100);
707
        $latestTrashItem = $trashService->trash(
708
            $locationService->loadLocation($folder2->contentInfo->mainLocationId)
709
        );
710
711
        $query = new Query();
712
        $query->filter = new Criterion\ContentId([
713
            $folder1->contentInfo->id,
714
            $folder2->contentInfo->id,
715
        ]);
716
717
        // Load all trashed locations, sorted by trashed date ASC
718
        $query->sortClauses = [new SortClause\Trash\DateTrashed(Query::SORT_ASC)];
719
        $searchResult = $trashService->findTrashItems($query);
720
        self::assertEquals(2, $searchResult->totalCount);
721
        self::assertEquals($firstTrashedItem->remoteId, $searchResult->items[0]->remoteId);
722
        self::assertEquals($latestTrashItem->remoteId, $searchResult->items[1]->remoteId);
723
724
        // Load all trashed locations, sorted by trashed date DESC
725
        $query->sortClauses = [new SortClause\Trash\DateTrashed(Query::SORT_DESC)];
726
        $searchResult = $trashService->findTrashItems($query);
727
        self::assertEquals(2, $searchResult->totalCount);
728
        self::assertEquals($latestTrashItem->remoteId, $searchResult->items[0]->remoteId);
729
        self::assertEquals($firstTrashedItem->remoteId, $searchResult->items[1]->remoteId);
730
    }
731
732
    /**
733
     * Test for the findTrashItems() method for it's result structure.
734
     *
735
     * @see \eZ\Publish\API\Repository\TrashService::findTrashItems()
736
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
737
     */
738
    public function testFindTrashItemsLimits()
739
    {
740
        $repository = $this->getRepository();
741
        $trashService = $repository->getTrashService();
742
743
        $this->createTrashItem();
744
745
        // Create a search query for all trashed items
746
        $query = new Query();
747
        $query->limit = 2;
748
749
        // Load all trashed locations
750
        $searchResult = $trashService->findTrashItems($query);
751
752
        $this->assertInstanceOf(
753
            SearchResult::class,
754
            $searchResult
755
        );
756
757
        // 4 trashed locations from the sub tree, but only 2 in results
758
        $this->assertCount(2, $searchResult->items);
759
        $this->assertEquals(4, $searchResult->count);
760
        $this->assertEquals(4, $searchResult->totalCount);
761
    }
762
763
    /**
764
     * Test for the findTrashItems() method.
765
     *
766
     * @see \eZ\Publish\API\Repository\TrashService::findTrashItems()
767
     * @depends \eZ\Publish\API\Repository\Tests\TrashServiceTest::testFindTrashItems
768
     */
769
    public function testFindTrashItemsLimitedAccess()
770
    {
771
        $repository = $this->getRepository();
772
        $trashService = $repository->getTrashService();
773
774
        /* BEGIN: Use Case */
775
        $this->createTrashItem();
776
777
        // Create a search query for all trashed items
778
        $query = new Query();
779
        $query->filter = new Criterion\LogicalAnd(
780
            [
781
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
782
            ]
783
        );
784
785
        // Create a user in the Editor user group.
786
        $user = $this->createUserVersion1();
787
788
        // Set the Editor user as current user, these users have no access to Trash by default.
789
        $repository->getPermissionResolver()->setCurrentUserReference($user);
790
791
        // Load all trashed locations
792
        $searchResult = $trashService->findTrashItems($query);
793
        /* END: Use Case */
794
795
        $this->assertInstanceOf(
796
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\SearchResult',
797
            $searchResult
798
        );
799
800
        // 0 trashed locations found, though 4 exist
801
        $this->assertEquals(0, $searchResult->count);
802
    }
803
804
    /**
805
     * Test Section Role Assignment Limitation against user/login.
806
     */
807
    public function testFindTrashItemsSubtreeLimitation()
808
    {
809
        $repository = $this->getRepository();
810
        $contentService = $repository->getContentService();
811
        $locationService = $repository->getLocationService();
812
        $contentTypeService = $repository->getContentTypeService();
813
        $trashService = $repository->getTrashService();
814
815
        $folder1 = $this->createFolder(['eng-GB' => 'Folder1'], 2);
816
        $folderLocationId = $folder1->contentInfo->mainLocationId;
817
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
818
        $newContent = $contentService->newContentCreateStruct($contentType, 'eng-US');
819
        $newContent->setField('name', 'Media');
820
        $draftContent = $contentService->createContent($newContent, [new LocationCreateStruct(['parentLocationId' => $folderLocationId])]);
821
        $published = $contentService->publishVersion($draftContent->versionInfo);
822
        $location = $locationService->loadLocation($published->contentInfo->mainLocationId);
823
        $trashService->trash($location);
824
825
        $this->createRoleWithPolicies('roleTrashCleaner', [
826
            [
827
                'module' => 'content',
828
                'function' => 'cleantrash'
829
            ],
830
            [
831
                'module' => 'content',
832
                'function' => 'read',
833
                'limitations' => [
834
                    new SubtreeLimitation(['limitationValues' => [sprintf('/1/2/%d/', $folderLocationId)]])
835
                ]
836
            ],
837
        ]);
838
        $user = $this->createCustomUserWithLogin(
839
            'user',
840
            '[email protected]',
841
            'roleTrashCleaners',
842
            'roleTrashCleaner'
843
        );
844
        $repository->getPermissionResolver()->setCurrentUserReference($user);
845
846
        $query = new Query();
847
        $query->filter = new Criterion\LogicalAnd(
848
            [
849
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
850
            ]
851
        );
852
853
        // Load all trashed locations
854
        $searchResult = $trashService->findTrashItems($query);
855
        /* END: Use Case */
856
        $this->assertInstanceOf(
857
            SearchResult::class,
858
            $searchResult
859
        );
860
861
        $this->assertEquals(1, count($searchResult->items));
862
    }
863
864
    /**
865
     * Test for the emptyTrash() method.
866
     *
867
     * @see \eZ\Publish\API\Repository\TrashService::emptyTrash()
868
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testFindTrashItems
869
     */
870
    public function testEmptyTrash()
871
    {
872
        $repository = $this->getRepository();
873
        $trashService = $repository->getTrashService();
874
        $contentService = $repository->getContentService();
875
876
        /* BEGIN: Use Case */
877
        $trashItem = $this->createTrashItem();
878
879
        // Empty the trash
880
        $trashService->emptyTrash();
881
882
        // Create a search query for all trashed items
883
        $query = new Query();
884
        $query->filter = new Criterion\LogicalAnd(
885
            [
886
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
887
            ]
888
        );
889
        // Load all trashed locations, search result should be empty
890
        $searchResult = $trashService->findTrashItems($query);
891
        /* END: Use Case */
892
893
        $this->assertEquals(0, $searchResult->count);
894
895
        // Try to load content
896
        $this->expectException(NotFoundException::class);
897
        $contentService->loadContent($trashItem->contentId);
898
    }
899
900
    /**
901
     * Test for the emptyTrash() method with user which has subtree limitations.
902
     *
903
     * @see \eZ\Publish\API\Repository\TrashService::emptyTrash()
904
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testFindTrashItems
905
     */
906
    public function testEmptyTrashForUserWithSubtreeLimitation()
907
    {
908
        $repository = $this->getRepository();
909
        $trashService = $repository->getTrashService();
910
        $contentService = $repository->getContentService();
911
912
        /* BEGIN: Use Case */
913
        $trashItem = $this->createTrashItem();
914
915
        $this->createRoleWithPolicies('roleTrashCleaner', [
916
            ['module' => 'content', 'function' => 'cleantrash'],
917
            ['module' => 'content', 'function' => 'read'],
918
        ]);
919
        $user = $this->createCustomUserWithLogin(
920
            'user',
921
            '[email protected]',
922
            'roleTrashCleaners',
923
            'roleTrashCleaner',
924
            new SubtreeLimitation(['limitationValues' => ['/1/2/']])
925
        );
926
        $repository->getPermissionResolver()->setCurrentUserReference($user);
927
928
        // Empty the trash
929
        $trashService->emptyTrash();
930
931
        // Create a search query for all trashed items
932
        $query = new Query();
933
        $query->filter = new Criterion\LogicalAnd(
934
            [
935
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
936
            ]
937
        );
938
        // Load all trashed locations, search result should be empty
939
        $searchResult = $trashService->findTrashItems($query);
940
        /* END: Use Case */
941
942
        $this->assertEquals(0, $searchResult->totalCount);
943
944
        // Try to load content
945
        $this->expectException(NotFoundException::class);
946
        $contentService->loadContent($trashItem->contentId);
947
    }
948
949
    /**
950
     * Test for the deleteTrashItem() method.
951
     *
952
     * @see \eZ\Publish\API\Repository\TrashService::deleteTrashItem()
953
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testFindTrashItems
954
     */
955
    public function testDeleteTrashItem()
956
    {
957
        $repository = $this->getRepository();
958
        $trashService = $repository->getTrashService();
959
        $locationService = $repository->getLocationService();
960
        $contentService = $repository->getContentService();
961
962
        $demoDesignLocationId = $this->generateId('location', 56);
963
        /* BEGIN: Use Case */
964
        // $demoDesignLocationId is the ID of the "Demo Design" location in an eZ
965
        // Publish demo installation
966
967
        $trashItem = $this->createTrashItem();
968
969
        // Trash one more location
970
        $trashService->trash(
971
            $locationService->loadLocation($demoDesignLocationId)
972
        );
973
974
        // Empty the trash
975
        $trashService->deleteTrashItem($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 967 can be null; however, eZ\Publish\API\Repositor...vice::deleteTrashItem() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
976
977
        // Create a search query for all trashed items
978
        $query = new Query();
979
        $query->filter = new Criterion\LogicalAnd(
980
            [
981
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
982
            ]
983
        );
984
985
        // Load all trashed locations, should only contain the Demo Design location
986
        $searchResult = $trashService->findTrashItems($query);
987
        /* END: Use Case */
988
989
        $foundIds = array_map(
990
            function ($trashItem) {
991
                return $trashItem->id;
992
            },
993
            $searchResult->items
994
        );
995
996
        $this->assertEquals(4, $searchResult->count);
997
        $this->assertTrue(
998
            in_array($demoDesignLocationId, $foundIds)
999
        );
1000
1001
        // Try to load Content
1002
        $this->expectException(NotFoundException::class);
1003
        $contentService->loadContent($trashItem->contentId);
1004
    }
1005
1006
    /**
1007
     * Test deleting a non existing trash item.
1008
     *
1009
     * @covers \eZ\Publish\API\Repository\TrashService::deleteTrashItem
1010
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1011
     */
1012
    public function testDeleteThrowsNotFoundExceptionForNonExistingTrashItem()
1013
    {
1014
        $repository = $this->getRepository();
1015
        $trashService = $repository->getTrashService();
1016
1017
        $trashService->deleteTrashItem($this->getTrashItemDouble(
1018
            12364,
1019
            12345,
1020
            12363
1021
        ));
1022
    }
1023
1024
    /**
1025
     * Returns an array with the remoteIds of all child locations of the
1026
     * <b>Community</b> location. It is stored in a local variable named
1027
     * <b>$remoteIds</b>.
1028
     *
1029
     * @return string[]
1030
     */
1031
    private function createRemoteIdList()
1032
    {
1033
        $repository = $this->getRepository();
1034
1035
        /* BEGIN: Inline */
1036
        // remoteId of the "Community" location in an eZ Publish demo installation
1037
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
1038
1039
        // Load the location service
1040
        $locationService = $repository->getLocationService();
1041
1042
        $remoteIds = [];
1043
        $children = $locationService->loadLocationChildren($locationService->loadLocationByRemoteId($mediaRemoteId));
1044
        foreach ($children->locations as $child) {
1045
            $remoteIds[] = $child->remoteId;
1046
            foreach ($locationService->loadLocationChildren($child)->locations as $grandChild) {
1047
                $remoteIds[] = $grandChild->remoteId;
1048
            }
1049
        }
1050
        /* END: Inline */
1051
1052
        return $remoteIds;
1053
    }
1054
1055
    /**
1056
     * @param Repository $repository
1057
     * @param int $parentLocationId
1058
     *
1059
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1060
     */
1061 View Code Duplication
    protected function createNewContentInPlaceTrashedOne(Repository $repository, $parentLocationId)
1062
    {
1063
        $contentService = $repository->getContentService();
1064
        $locationService = $repository->getLocationService();
1065
        $contentTypeService = $repository->getContentTypeService();
1066
1067
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
1068
        $newContent = $contentService->newContentCreateStruct($contentType, 'eng-US');
1069
        $newContent->setField('name', 'Media');
1070
1071
        $location = $locationService->newLocationCreateStruct($parentLocationId);
1072
1073
        $draftContent = $contentService->createContent($newContent, [$location]);
1074
1075
        return $contentService->publishVersion($draftContent->versionInfo);
1076
    }
1077
1078
    /**
1079
     * @param URLAliasService $urlAliasService
1080
     * @param string $urlPath Url alias path
1081
     *
1082
     * @return \eZ\Publish\API\Repository\Values\Content\URLAlias
1083
     */
1084
    private function assertAliasExists(URLAliasService $urlAliasService, $urlPath)
1085
    {
1086
        $urlAlias = $urlAliasService->lookup($urlPath);
1087
1088
        $this->assertInstanceOf('\eZ\Publish\API\Repository\Values\Content\URLAlias', $urlAlias);
1089
1090
        return $urlAlias;
1091
    }
1092
1093
    /**
1094
     * @param URLAliasService $urlAliasService
1095
     * @param string $urlPath Url alias path
1096
     */
1097
    private function assertAliasNotExists(URLAliasService $urlAliasService, $urlPath)
0 ignored issues
show
Unused Code introduced by
The parameter $urlAliasService is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1098
    {
1099
        try {
1100
            $this->getRepository()->getURLAliasService()->lookup($urlPath);
1101
            $this->fail(sprintf('Alias [%s] should not exists', $urlPath));
1102
        } catch (\eZ\Publish\API\Repository\Exceptions\NotFoundException $e) {
1103
            $this->assertTrue(true);
1104
        }
1105
    }
1106
1107
    /**
1108
     * Get Test Double for TrashItem for exception testing and similar.
1109
     *
1110
     * @param int $trashId
1111
     * @param int $contentId
1112
     * @param int $parentLocationId
1113
     *
1114
     * @return \eZ\Publish\API\Repository\Values\Content\TrashItem
1115
     */
1116
    private function getTrashItemDouble(int $trashId, int $contentId = 44, int $parentLocationId = 2): APITrashItem
1117
    {
1118
        return new TrashItem([
1119
            'id' => $trashId,
1120
            'parentLocationId' => $parentLocationId,
1121
            'contentInfo' => new ContentInfo(['id' => $contentId]),
1122
        ]);
1123
    }
1124
}
1125