Completed
Push — ezp25636_user_cant_access_tras... ( 501f47...7d6505 )
by
unknown
56:19 queued 43:35
created

testFindTrashItemsLimitedAccess()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 1
dl 0
loc 34
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the TrashServiceTest 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\Repository;
12
use eZ\Publish\API\Repository\URLAliasService;
13
use eZ\Publish\API\Repository\Values\User\User;
14
use eZ\Publish\API\Repository\Values\Content\Location;
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\Exceptions\NotFoundException;
18
19
/**
20
 * Test case for operations in the TrashService using in memory storage.
21
 *
22
 * @see eZ\Publish\API\Repository\TrashService
23
 * @group integration
24
 * @group trash
25
 */
26
class TrashServiceTest extends BaseTrashServiceTest
27
{
28
    /**
29
     * Test for the trash() method.
30
     *
31
     * @see \eZ\Publish\API\Repository\TrashService::trash()
32
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationByRemoteId
33
     */
34
    public function testTrash()
35
    {
36
        /* BEGIN: Use Case */
37
        $trashItem = $this->createTrashItem();
38
        /* END: Use Case */
39
40
        $this->assertInstanceOf(
41
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\TrashItem',
42
            $trashItem
43
        );
44
    }
45
46
    /**
47
     * Test for the trash() method.
48
     *
49
     * @see \eZ\Publish\API\Repository\TrashService::trash()
50
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
51
     */
52
    public function testTrashSetsExpectedTrashItemProperties()
53
    {
54
        $repository = $this->getRepository();
55
56
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
57
58
        // Load the location that will be trashed
59
        $location = $repository->getLocationService()
60
            ->loadLocationByRemoteId($mediaRemoteId);
61
62
        $expected = array(
63
            'id' => $location->id,
64
            'depth' => $location->depth,
65
            'hidden' => $location->hidden,
66
            'invisible' => $location->invisible,
67
            'parentLocationId' => $location->parentLocationId,
68
            'pathString' => $location->pathString,
69
            'priority' => $location->priority,
70
            'remoteId' => $location->remoteId,
71
            'sortField' => $location->sortField,
72
            'sortOrder' => $location->sortOrder,
73
        );
74
75
        $trashItem = $this->createTrashItem();
76
77
        $this->assertPropertiesCorrect($expected, $trashItem);
78
    }
79
80
    /**
81
     * Test for the trash() method.
82
     *
83
     * @see \eZ\Publish\API\Repository\TrashService::trash()
84
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
85
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
86
     */
87
    public function testTrashRemovesLocationFromMainStorage()
88
    {
89
        $repository = $this->getRepository();
90
91
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
92
93
        /* BEGIN: Use Case */
94
        $this->createTrashItem();
95
96
        // Load the location service
97
        $locationService = $repository->getLocationService();
98
99
        // This call will fail with a "NotFoundException", because the media
100
        // location was marked as trashed in the main storage
101
        $locationService->loadLocationByRemoteId($mediaRemoteId);
102
        /* END: Use Case */
103
    }
104
105
    /**
106
     * Test for the trash() method.
107
     *
108
     * @see \eZ\Publish\API\Repository\TrashService::trash()
109
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
110
     */
111
    public function testTrashRemovesChildLocationsFromMainStorage()
112
    {
113
        $repository = $this->getRepository();
114
115
        /* BEGIN: Use Case */
116
        $remoteIds = $this->createRemoteIdList();
117
118
        $this->createTrashItem();
119
120
        // All invocations to loadLocationByRemoteId() to one of the above
121
        // collected remoteIds will return in an "NotFoundException"
122
        /* END: Use Case */
123
124
        $locationService = $repository->getLocationService();
125
        foreach ($remoteIds as $remoteId) {
126
            try {
127
                $locationService->loadLocationByRemoteId($remoteId);
128
                $this->fail("Location '{$remoteId}' should exist.'");
129
            } catch (NotFoundException $e) {
130
                // echo $e->getFile(), ' +', $e->getLine(), PHP_EOL;
131
            }
132
        }
133
134
        $this->assertGreaterThan(
135
            0,
136
            count($remoteIds),
137
            "There should be at least one 'Community' child location."
138
        );
139
    }
140
141
    /**
142
     * Test for the trash() method.
143
     *
144
     * @see \eZ\Publish\API\Repository\TrashService::trash()
145
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
146
     */
147 View Code Duplication
    public function testTrashDecrementsChildCountOnParentLocation()
148
    {
149
        $repository = $this->getRepository();
150
        $locationService = $repository->getLocationService();
151
152
        $baseLocationId = $this->generateId('location', 1);
153
154
        $location = $locationService->loadLocation($baseLocationId);
155
156
        $childCount = $locationService->getLocationChildCount($location);
157
158
        $this->createTrashItem();
159
160
        $this->refreshSearch($repository);
161
162
        $this->assertEquals(
163
            $childCount - 1,
164
            $locationService->getLocationChildCount($location)
165
        );
166
    }
167
168
    /**
169
     * Test for the loadTrashItem() method.
170
     *
171
     * @see \eZ\Publish\API\Repository\TrashService::loadTrashItem()
172
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
173
     */
174
    public function testLoadTrashItem()
175
    {
176
        $repository = $this->getRepository();
177
        $trashService = $repository->getTrashService();
178
179
        /* BEGIN: Use Case */
180
        $trashItem = $this->createTrashItem();
181
182
        // Reload the trash item
183
        $trashItemReloaded = $trashService->loadTrashItem($trashItem->id);
184
        /* END: Use Case */
185
186
        $this->assertInstanceOf(
187
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\TrashItem',
188
            $trashItemReloaded
189
        );
190
191
        $this->assertEquals(
192
            $trashItem->pathString,
0 ignored issues
show
Documentation introduced by
The property $pathString is declared protected in eZ\Publish\API\Repository\Values\Content\Location. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

Since the property has write access only, you can use the @property-write annotation instead.

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

See also the PhpDoc documentation for @property.

Loading history...
193
            $trashItemReloaded->pathString
0 ignored issues
show
Documentation introduced by
The property $pathString is declared protected in eZ\Publish\API\Repository\Values\Content\Location. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

Since the property has write access only, you can use the @property-write annotation instead.

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

See also the PhpDoc documentation for @property.

Loading history...
194
        );
195
    }
196
197
    /**
198
     * Test for the loadTrashItem() method.
199
     *
200
     * @see \eZ\Publish\API\Repository\TrashService::loadTrashItem()
201
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
202
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testLoadTrashItem
203
     */
204
    public function testLoadTrashItemThrowsNotFoundException()
205
    {
206
        $repository = $this->getRepository();
207
208
        $nonExistingTrashId = $this->generateId('trash', 2342);
209
        /* BEGIN: Use Case */
210
        $trashService = $repository->getTrashService();
211
212
        // This call will fail with a "NotFoundException", because no trash item
213
        // with the ID 1342 should exist in an eZ Publish demo installation
214
        $trashService->loadTrashItem($nonExistingTrashId);
215
        /* END: Use Case */
216
    }
217
218
    /**
219
     * Test for the recover() method.
220
     *
221
     * @see \eZ\Publish\API\Repository\TrashService::recover()
222
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
223
     */
224
    public function testRecover()
225
    {
226
        $repository = $this->getRepository();
227
        $trashService = $repository->getTrashService();
228
        $locationService = $repository->getLocationService();
229
230
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
231
232
        /* BEGIN: Use Case */
233
        $trashItem = $this->createTrashItem();
234
235
        // Recover the trashed item
236
        $location = $trashService->recover($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 233 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...
237
238
        // Load the recovered location
239
        $locationReloaded = $locationService->loadLocationByRemoteId(
240
            $mediaRemoteId
241
        );
242
        /* END: Use Case */
243
244
        $this->assertInstanceOf(
245
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
246
            $location
247
        );
248
249
        $this->assertEquals(
250
            $location->pathString,
251
            $locationReloaded->pathString
252
        );
253
254
        try {
255
            $trashService->loadTrashItem($trashItem->id);
256
            $this->fail('Trash item was not removed after being recovered.');
257
        } catch (NotFoundException $e) {
258
            // All well
259
        }
260
    }
261
262
    /**
263
     * Test for the trash() method.
264
     *
265
     * @see \eZ\Publish\API\Repository\TrashService::recover()
266
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
267
     *
268
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
269
     */
270 View Code Duplication
    public function testNotFoundAliasAfterRemoveIt()
271
    {
272
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
273
274
        $repository = $this->getRepository();
275
        $trashService = $repository->getTrashService();
276
        $urlAliasService = $repository->getURLAliasService();
277
        $locationService = $repository->getLocationService();
278
279
        // Double ->lookup() call because there where issue that one call was not enough to spot bug
280
        $urlAliasService->lookup('/Media');
281
        $urlAliasService->lookup('/Media');
282
283
        $mediaLocation = $locationService->loadLocationByRemoteId($mediaRemoteId);
284
        $trashService->trash($mediaLocation);
285
286
        $urlAliasService->lookup('/Media');
287
    }
288
289
    /**
290
     * Test for the recover() method.
291
     *
292
     * @see \eZ\Publish\API\Repository\TrashService::recover()
293
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
294
     */
295
    public function testAliasesForRemovedItems()
296
    {
297
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
298
299
        $repository = $this->getRepository();
300
        $trashService = $repository->getTrashService();
301
        $urlAliasService = $repository->getURLAliasService();
302
        $locationService = $repository->getLocationService();
303
304
        // Double ->lookup() call because there where issue that one call was not enough to spot bug
305
        $urlAliasService->lookup('/Media');
306
        $trashedLocationAlias = $urlAliasService->lookup('/Media');
307
308
        $mediaLocation = $locationService->loadLocationByRemoteId($mediaRemoteId);
309
        $trashItem = $trashService->trash($mediaLocation);
310
        $this->assertAliasNotExists($urlAliasService, '/Media');
311
312
        $this->createNewContentInPlaceTrashedOne($repository, $mediaLocation->parentLocationId);
313
314
        $createdLocationAlias = $urlAliasService->lookup('/Media');
315
316
        $this->assertNotEquals(
317
            $trashedLocationAlias->destination,
318
            $createdLocationAlias->destination,
319
            'Destination for /media url should changed'
320
        );
321
322
        $recoveredLocation = $trashService->recover($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $trashService->trash($mediaLocation) on line 309 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
        $recoveredLocationAlias = $urlAliasService->lookup('/Media2');
324
        $recoveredLocationAliasReverse = $urlAliasService->reverseLookup($recoveredLocation);
325
326
        $this->assertEquals($recoveredLocationAlias->destination, $recoveredLocationAliasReverse->destination);
327
328
        $this->assertNotEquals($recoveredLocationAliasReverse->destination, $trashedLocationAlias->destination);
329
        $this->assertNotEquals($recoveredLocationAliasReverse->destination, $createdLocationAlias->destination);
330
    }
331
332
    /**
333
     * Test for the recover() method.
334
     *
335
     * @see \eZ\Publish\API\Repository\TrashService::recover()
336
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testRecover
337
     */
338
    public function testRecoverDoesNotRestoreChildLocations()
339
    {
340
        $repository = $this->getRepository();
341
        $trashService = $repository->getTrashService();
342
        $locationService = $repository->getLocationService();
343
344
        $remoteIds = $this->createRemoteIdList();
345
346
        // Unset remote ID of actually restored location
347
        unset($remoteIds[array_search('3f6d92f8044aed134f32153517850f5a', $remoteIds)]);
348
349
        $trashItem = $this->createTrashItem();
350
351
        $trashService->recover($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 349 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...
352
353
        $this->assertGreaterThan(
354
            0,
355
            count($remoteIds),
356
            "There should be at least one 'Community' child location."
357
        );
358
359
        // None of the child locations will be available again
360
        foreach ($remoteIds as $remoteId) {
361
            try {
362
                $locationService->loadLocationByRemoteId($remoteId);
363
                $this->fail(
364
                    sprintf(
365
                        'Location with remote ID "%s" unexpectedly restored.',
366
                        $remoteId
367
                    )
368
                );
369
            } catch (NotFoundException $e) {
370
                // All well
371
            }
372
        }
373
374
        try {
375
            $trashService->loadTrashItem($trashItem->id);
376
            $this->fail('Trash item was not removed after being recovered.');
377
        } catch (NotFoundException $e) {
378
            // All well
379
        }
380
    }
381
382
    /**
383
     * Test for the recover() method.
384
     *
385
     * @see \eZ\Publish\API\Repository\TrashService::recover($trashItem, $newParentLocation)
386
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testRecover
387
     *
388
     * @todo Fix naming
389
     */
390
    public function testRecoverWithLocationCreateStructParameter()
391
    {
392
        $repository = $this->getRepository();
393
        $trashService = $repository->getTrashService();
394
        $locationService = $repository->getLocationService();
395
396
        $homeLocationId = $this->generateId('location', 2);
397
        /* BEGIN: Use Case */
398
        // $homeLocationId is the ID of the "Home" location in an eZ Publish
399
        // demo installation
400
401
        $trashItem = $this->createTrashItem();
402
403
        // Get the new parent location
404
        $newParentLocation = $locationService->loadLocation($homeLocationId);
405
406
        // Recover location with new location
407
        $location = $trashService->recover($trashItem, $newParentLocation);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 401 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...
408
        /* END: Use Case */
409
410
        $this->assertPropertiesCorrect(
411
            array(
412
                'remoteId' => $trashItem->remoteId,
413
                'parentLocationId' => $homeLocationId,
414
                // Not the full sub tree is restored
415
                'depth' => $newParentLocation->depth + 1,
416
                'hidden' => false,
417
                'invisible' => $trashItem->invisible,
0 ignored issues
show
Documentation introduced by
The property $invisible is declared protected in eZ\Publish\API\Repository\Values\Content\Location. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

Since the property has write access only, you can use the @property-write annotation instead.

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

See also the PhpDoc documentation for @property.

Loading history...
418
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $location->id) . '/',
419
                'priority' => 0,
420
                'sortField' => Location::SORT_FIELD_NAME,
421
                'sortOrder' => Location::SORT_ORDER_ASC,
422
            ),
423
            $location
424
        );
425
426
        try {
427
            $trashService->loadTrashItem($trashItem->id);
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repository\Values\Content\Location. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

Since the property has write access only, you can use the @property-write annotation instead.

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

See also the PhpDoc documentation for @property.

Loading history...
428
            $this->fail('Trash item was not removed after being recovered.');
429
        } catch (NotFoundException $e) {
430
            // All well
431
        }
432
    }
433
434
    /**
435
     * Test for the recover() method.
436
     *
437
     * @see \eZ\Publish\API\Repository\TrashService::recover($trashItem)
438
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testRecover
439
     */
440
    public function testRecoverIncrementsChildCountOnOriginalParent()
441
    {
442
        $repository = $this->getRepository();
443
        $trashService = $repository->getTrashService();
444
        $locationService = $repository->getLocationService();
445
446
        $location = $locationService->loadLocation($this->generateId('location', 1));
447
448
        $trashItem = $this->createTrashItem();
449
450
        $this->refreshSearch($repository);
451
452
        /* BEGIN: Use Case */
453
        $childCount = $locationService->getLocationChildCount($location);
454
455
        // Recover location with new location
456
        $trashService->recover($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 448 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...
457
        /* END: Use Case */
458
459
        $this->refreshSearch($repository);
460
461
        $this->assertEquals(
462
            $childCount + 1,
463
            $locationService->getLocationChildCount($location)
464
        );
465
466
        try {
467
            $trashService->loadTrashItem($trashItem->id);
468
            $this->fail('Trash item was not removed after being recovered.');
469
        } catch (NotFoundException $e) {
470
            // All well
471
        }
472
    }
473
474
    /**
475
     * Test for the recover() method.
476
     *
477
     * @see \eZ\Publish\API\Repository\TrashService::recover($trashItem, $newParentLocation)
478
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testRecoverWithLocationCreateStructParameter
479
     */
480
    public function testRecoverWithLocationCreateStructParameterIncrementsChildCountOnNewParent()
481
    {
482
        $repository = $this->getRepository();
483
        $trashService = $repository->getTrashService();
484
        $locationService = $repository->getLocationService();
485
486
        $homeLocationId = $this->generateId('location', 2);
487
488
        $location = $locationService->loadLocation($homeLocationId);
489
490
        $childCount = $locationService->getLocationChildCount($location);
491
492
        /* BEGIN: Use Case */
493
        // $homeLocationId is the ID of the "Home" location in an eZ Publish
494
        // demo installation
495
496
        $trashItem = $this->createTrashItem();
497
498
        // Get the new parent location
499
        $newParentLocation = $locationService->loadLocation($homeLocationId);
500
501
        // Recover location with new location
502
        $trashService->recover($trashItem, $newParentLocation);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 496 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...
503
        /* END: Use Case */
504
505
        $this->refreshSearch($repository);
506
507
        $this->assertEquals(
508
            $childCount + 1,
509
            $locationService->getLocationChildCount($location)
510
        );
511
512
        try {
513
            $trashService->loadTrashItem($trashItem->id);
514
            $this->fail('Trash item was not removed after being recovered.');
515
        } catch (NotFoundException $e) {
516
            // All well
517
        }
518
    }
519
520
    /**
521
     * Test for the findTrashItems() method.
522
     *
523
     * @see \eZ\Publish\API\Repository\TrashService::findTrashItems()
524
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
525
     */
526 View Code Duplication
    public function testFindTrashItems()
527
    {
528
        $repository = $this->getRepository();
529
        $trashService = $repository->getTrashService();
530
531
        /* BEGIN: Use Case */
532
        $this->createTrashItem();
533
534
        // Create a search query for all trashed items
535
        $query = new Query();
536
        $query->filter = new Criterion\LogicalAnd(
537
            array(
538
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
539
            )
540
        );
541
542
        // Load all trashed locations
543
        $searchResult = $trashService->findTrashItems($query);
544
        /* END: Use Case */
545
546
        $this->assertInstanceOf(
547
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\SearchResult',
548
            $searchResult
549
        );
550
551
        // 4 trashed locations from the sub tree
552
        $this->assertEquals(4, $searchResult->count);
553
    }
554
555
    /**
556
     * Test for the findTrashItems() method.
557
     *
558
     * @see \eZ\Publish\API\Repository\TrashService::findTrashItems()
559
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testTrash
560
     * @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
561
     */
562
    public function testFindTrashItemsLimitedAccess(User $user)
563
    {
564
        $repository = $this->getRepository();
565
        $trashService = $repository->getTrashService();
566
567
        /* BEGIN: Use Case */
568
        $this->createTrashItem();
569
570
        // Create a search query for all trashed items
571
        $query = new Query();
572
        $query->filter = new Criterion\LogicalAnd(
573
            array(
574
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
575
            )
576
        );
577
578
        // Load user service
579
        $userService = $repository->getUserService();
580
581
        // Set an Editor user as current user, these users have no access to Trash by default
582
        $repository->setCurrentUser($userService->loadUser($user->getUserId()));
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...
583
584
        // Load all trashed locations
585
        $searchResult = $trashService->findTrashItems($query);
586
        /* END: Use Case */
587
588
        $this->assertInstanceOf(
589
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\SearchResult',
590
            $searchResult
591
        );
592
593
        // 0 trashed locations found, though 4 exist
594
        $this->assertEquals(0, $searchResult->count);
595
    }
596
597
    /**
598
     * Test for the emptyTrash() method.
599
     *
600
     * @see \eZ\Publish\API\Repository\TrashService::emptyTrash()
601
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testFindTrashItems
602
     */
603 View Code Duplication
    public function testEmptyTrash()
604
    {
605
        $repository = $this->getRepository();
606
        $trashService = $repository->getTrashService();
607
608
        /* BEGIN: Use Case */
609
        $this->createTrashItem();
610
611
        // Empty the trash
612
        $trashService->emptyTrash();
613
614
        // Create a search query for all trashed items
615
        $query = new Query();
616
        $query->filter = new Criterion\LogicalAnd(
617
            array(
618
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
619
            )
620
        );
621
622
        // Load all trashed locations, search result should be empty
623
        $searchResult = $trashService->findTrashItems($query);
624
        /* END: Use Case */
625
626
        $this->assertEquals(0, $searchResult->count);
627
    }
628
629
    /**
630
     * Test for the deleteTrashItem() method.
631
     *
632
     * @see \eZ\Publish\API\Repository\TrashService::deleteTrashItem()
633
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testFindTrashItems
634
     */
635
    public function testDeleteTrashItem()
636
    {
637
        $repository = $this->getRepository();
638
        $trashService = $repository->getTrashService();
639
        $locationService = $repository->getLocationService();
640
641
        $demoDesignLocationId = $this->generateId('location', 56);
642
        /* BEGIN: Use Case */
643
        // $demoDesignLocationId is the ID of the "Demo Design" location in an eZ
644
        // Publish demo installation
645
646
        $trashItem = $this->createTrashItem();
647
648
        // Trash one more location
649
        $trashService->trash(
650
            $locationService->loadLocation($demoDesignLocationId)
651
        );
652
653
        // Empty the trash
654
        $trashService->deleteTrashItem($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 646 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...
655
656
        // Create a search query for all trashed items
657
        $query = new Query();
658
        $query->filter = new Criterion\LogicalAnd(
659
            array(
660
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
661
            )
662
        );
663
664
        // Load all trashed locations, should only contain the Demo Design location
665
        $searchResult = $trashService->findTrashItems($query);
666
        /* END: Use Case */
667
668
        $foundIds = array_map(
669
            function ($trashItem) {
670
                return $trashItem->id;
671
            },
672
            $searchResult->items
673
        );
674
675
        $this->assertEquals(4, $searchResult->count);
676
        $this->assertTrue(
677
            array_search($demoDesignLocationId, $foundIds) !== false
678
        );
679
    }
680
681
    /**
682
     * Returns an array with the remoteIds of all child locations of the
683
     * <b>Community</b> location. It is stored in a local variable named
684
     * <b>$remoteIds</b>.
685
     *
686
     * @return string[]
687
     */
688
    private function createRemoteIdList()
689
    {
690
        $repository = $this->getRepository();
691
692
        /* BEGIN: Inline */
693
        // remoteId of the "Community" location in an eZ Publish demo installation
694
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
695
696
        // Load the location service
697
        $locationService = $repository->getLocationService();
698
699
        $remoteIds = array();
700
        $children = $locationService->loadLocationChildren($locationService->loadLocationByRemoteId($mediaRemoteId));
701
        foreach ($children->locations as $child) {
702
            $remoteIds[] = $child->remoteId;
703
            foreach ($locationService->loadLocationChildren($child)->locations as $grandChild) {
704
                $remoteIds[] = $grandChild->remoteId;
705
            }
706
        }
707
        /* END: Inline */
708
709
        return $remoteIds;
710
    }
711
712
    /**
713
     * @param Repository $repository
714
     * @param int $parentLocationId
715
     *
716
     * @return \eZ\Publish\API\Repository\Values\Content\Content
717
     */
718
    protected function createNewContentInPlaceTrashedOne(Repository $repository, $parentLocationId)
719
    {
720
        $contentService = $repository->getContentService();
721
        $locationService = $repository->getLocationService();
722
        $contentTypeService = $repository->getContentTypeService();
723
724
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
725
        $newContent = $contentService->newContentCreateStruct($contentType, 'eng-US');
726
        $newContent->setField('name', 'Media');
727
728
        $location = $locationService->newLocationCreateStruct($parentLocationId);
729
730
        $draftContent = $contentService->createContent($newContent, [$location]);
731
732
        return $contentService->publishVersion($draftContent->versionInfo);
733
    }
734
735
    /**
736
     * @param URLAliasService $urlAliasService
737
     * @param string $urlPath Url alias path
738
     *
739
     * @return \eZ\Publish\API\Repository\Values\Content\URLAlias
740
     */
741
    private function assertAliasExists(URLAliasService $urlAliasService, $urlPath)
742
    {
743
        $urlAlias = $urlAliasService->lookup($urlPath);
744
745
        $this->assertInstanceOf('\eZ\Publish\API\Repository\Values\Content\URLAlias', $urlAlias);
746
747
        return $urlAlias;
748
    }
749
750
    /**
751
     * @param URLAliasService $urlAliasService
752
     * @param string $urlPath Url alias path
753
     */
754
    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...
755
    {
756
        try {
757
            $this->getRepository()->getURLAliasService()->lookup($urlPath);
758
            $this->fail(sprintf('Alias [%s] should not exists', $urlPath));
759
        } catch (\eZ\Publish\API\Repository\Exceptions\NotFoundException $e) {
760
            $this->assertTrue(true);
761
        }
762
    }
763
}
764