Completed
Push — 6.7 ( a124d5...5e47d1 )
by André
50:32 queued 36:29
created

TrashServiceTest::testTrash()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 11
rs 9.4285
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::testFindTrashItems
560
     */
561
    public function testFindTrashItemsLimitedAccess()
562
    {
563
        $repository = $this->getRepository();
564
        $trashService = $repository->getTrashService();
565
566
        /* BEGIN: Use Case */
567
        $this->createTrashItem();
568
569
        // Create a search query for all trashed items
570
        $query = new Query();
571
        $query->filter = new Criterion\LogicalAnd(
572
            array(
573
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
574
            )
575
        );
576
577
        // Create a user in the Editor user group.
578
        $user = $this->createUserVersion1();
579
580
        // Set the Editor user as current user, these users have no access to Trash by default.
581
        $repository->getPermissionResolver()->setCurrentUserReference($user);
582
583
        // Load all trashed locations
584
        $searchResult = $trashService->findTrashItems($query);
585
        /* END: Use Case */
586
587
        $this->assertInstanceOf(
588
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\SearchResult',
589
            $searchResult
590
        );
591
592
        // 0 trashed locations found, though 4 exist
593
        $this->assertEquals(0, $searchResult->count);
594
    }
595
596
    /**
597
     * Test for the emptyTrash() method.
598
     *
599
     * @see \eZ\Publish\API\Repository\TrashService::emptyTrash()
600
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testFindTrashItems
601
     */
602 View Code Duplication
    public function testEmptyTrash()
603
    {
604
        $repository = $this->getRepository();
605
        $trashService = $repository->getTrashService();
606
607
        /* BEGIN: Use Case */
608
        $this->createTrashItem();
609
610
        // Empty the trash
611
        $trashService->emptyTrash();
612
613
        // Create a search query for all trashed items
614
        $query = new Query();
615
        $query->filter = new Criterion\LogicalAnd(
616
            array(
617
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
618
            )
619
        );
620
621
        // Load all trashed locations, search result should be empty
622
        $searchResult = $trashService->findTrashItems($query);
623
        /* END: Use Case */
624
625
        $this->assertEquals(0, $searchResult->count);
626
    }
627
628
    /**
629
     * Test for the deleteTrashItem() method.
630
     *
631
     * @see \eZ\Publish\API\Repository\TrashService::deleteTrashItem()
632
     * @depends eZ\Publish\API\Repository\Tests\TrashServiceTest::testFindTrashItems
633
     */
634
    public function testDeleteTrashItem()
635
    {
636
        $repository = $this->getRepository();
637
        $trashService = $repository->getTrashService();
638
        $locationService = $repository->getLocationService();
639
640
        $demoDesignLocationId = $this->generateId('location', 56);
641
        /* BEGIN: Use Case */
642
        // $demoDesignLocationId is the ID of the "Demo Design" location in an eZ
643
        // Publish demo installation
644
645
        $trashItem = $this->createTrashItem();
646
647
        // Trash one more location
648
        $trashService->trash(
649
            $locationService->loadLocation($demoDesignLocationId)
650
        );
651
652
        // Empty the trash
653
        $trashService->deleteTrashItem($trashItem);
0 ignored issues
show
Bug introduced by
It seems like $trashItem defined by $this->createTrashItem() on line 645 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...
654
655
        // Create a search query for all trashed items
656
        $query = new Query();
657
        $query->filter = new Criterion\LogicalAnd(
658
            array(
659
                new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
660
            )
661
        );
662
663
        // Load all trashed locations, should only contain the Demo Design location
664
        $searchResult = $trashService->findTrashItems($query);
665
        /* END: Use Case */
666
667
        $foundIds = array_map(
668
            function ($trashItem) {
669
                return $trashItem->id;
670
            },
671
            $searchResult->items
672
        );
673
674
        $this->assertEquals(4, $searchResult->count);
675
        $this->assertTrue(
676
            array_search($demoDesignLocationId, $foundIds) !== false
677
        );
678
    }
679
680
    /**
681
     * Returns an array with the remoteIds of all child locations of the
682
     * <b>Community</b> location. It is stored in a local variable named
683
     * <b>$remoteIds</b>.
684
     *
685
     * @return string[]
686
     */
687
    private function createRemoteIdList()
688
    {
689
        $repository = $this->getRepository();
690
691
        /* BEGIN: Inline */
692
        // remoteId of the "Community" location in an eZ Publish demo installation
693
        $mediaRemoteId = '75c715a51699d2d309a924eca6a95145';
694
695
        // Load the location service
696
        $locationService = $repository->getLocationService();
697
698
        $remoteIds = array();
699
        $children = $locationService->loadLocationChildren($locationService->loadLocationByRemoteId($mediaRemoteId));
700
        foreach ($children->locations as $child) {
701
            $remoteIds[] = $child->remoteId;
702
            foreach ($locationService->loadLocationChildren($child)->locations as $grandChild) {
703
                $remoteIds[] = $grandChild->remoteId;
704
            }
705
        }
706
        /* END: Inline */
707
708
        return $remoteIds;
709
    }
710
711
    /**
712
     * @param Repository $repository
713
     * @param int $parentLocationId
714
     *
715
     * @return \eZ\Publish\API\Repository\Values\Content\Content
716
     */
717
    protected function createNewContentInPlaceTrashedOne(Repository $repository, $parentLocationId)
718
    {
719
        $contentService = $repository->getContentService();
720
        $locationService = $repository->getLocationService();
721
        $contentTypeService = $repository->getContentTypeService();
722
723
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
724
        $newContent = $contentService->newContentCreateStruct($contentType, 'eng-US');
725
        $newContent->setField('name', 'Media');
726
727
        $location = $locationService->newLocationCreateStruct($parentLocationId);
728
729
        $draftContent = $contentService->createContent($newContent, [$location]);
730
731
        return $contentService->publishVersion($draftContent->versionInfo);
732
    }
733
734
    /**
735
     * @param URLAliasService $urlAliasService
736
     * @param string $urlPath Url alias path
737
     *
738
     * @return \eZ\Publish\API\Repository\Values\Content\URLAlias
739
     */
740
    private function assertAliasExists(URLAliasService $urlAliasService, $urlPath)
741
    {
742
        $urlAlias = $urlAliasService->lookup($urlPath);
743
744
        $this->assertInstanceOf('\eZ\Publish\API\Repository\Values\Content\URLAlias', $urlAlias);
745
746
        return $urlAlias;
747
    }
748
749
    /**
750
     * @param URLAliasService $urlAliasService
751
     * @param string $urlPath Url alias path
752
     */
753
    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...
754
    {
755
        try {
756
            $this->getRepository()->getURLAliasService()->lookup($urlPath);
757
            $this->fail(sprintf('Alias [%s] should not exists', $urlPath));
758
        } catch (\eZ\Publish\API\Repository\Exceptions\NotFoundException $e) {
759
            $this->assertTrue(true);
760
        }
761
    }
762
}
763