Completed
Push — EZP-31644 ( 2e0a1e...93bb44 )
by
unknown
19:12
created

testLoadContentByRemoteIdWithSecondParameter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22

Duplication

Lines 22
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 22
loc 22
rs 9.568
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the ContentServiceTest 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\Values\Content\Content;
12
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
13
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
14
use eZ\Publish\API\Repository\Values\Content\ContentMetadataUpdateStruct;
15
use eZ\Publish\API\Repository\Values\Content\ContentUpdateStruct;
16
use eZ\Publish\API\Repository\Values\Content\Field;
17
use eZ\Publish\API\Repository\Values\Content\Location;
18
use eZ\Publish\API\Repository\Values\Content\TranslationInfo;
19
use eZ\Publish\API\Repository\Values\Content\URLAlias;
20
use eZ\Publish\API\Repository\Values\Content\Relation;
21
use eZ\Publish\API\Repository\Values\Content\VersionInfo;
22
use eZ\Publish\API\Repository\Values\User\Limitation\SectionLimitation;
23
use eZ\Publish\API\Repository\Values\User\Limitation\LocationLimitation;
24
use eZ\Publish\API\Repository\Values\User\Limitation\ContentTypeLimitation;
25
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
26
use DOMDocument;
27
use Exception;
28
29
/**
30
 * Test case for operations in the ContentService using in memory storage.
31
 *
32
 * @see eZ\Publish\API\Repository\ContentService
33
 * @group content
34
 */
35
class ContentServiceTest extends BaseContentServiceTest
36
{
37
    const ENG_GB = 'eng-GB';
38
    const ENG_US = 'eng-US';
39
40
    /**
41
     * Test for the newContentCreateStruct() method.
42
     *
43
     * @see \eZ\Publish\API\Repository\ContentService::newContentCreateStruct()
44
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
45
     * @group user
46
     * @group field-type
47
     */
48
    public function testNewContentCreateStruct()
49
    {
50
        $repository = $this->getRepository();
51
52
        /* BEGIN: Use Case */
53
        // Create a content type
54
        $contentTypeService = $repository->getContentTypeService();
55
56
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
57
58
        $contentService = $repository->getContentService();
59
60
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
61
        /* END: Use Case */
62
63
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct', $contentCreate);
64
    }
65
66
    /**
67
     * Test for the createContent() method.
68
     *
69
     * @return \eZ\Publish\API\Repository\Values\Content\Content
70
     *
71
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
72
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentCreateStruct
73
     * @group user
74
     * @group field-type
75
     */
76
    public function testCreateContent()
77
    {
78
        if ($this->isVersion4()) {
79
            $this->markTestSkipped('This test requires eZ Publish 5');
80
        }
81
82
        $repository = $this->getRepository();
83
84
        /* BEGIN: Use Case */
85
        $contentTypeService = $repository->getContentTypeService();
86
87
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
88
89
        $contentService = $repository->getContentService();
90
91
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
92
        $contentCreate->setField('name', 'My awesome forum');
93
94
        $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
95
        $contentCreate->alwaysAvailable = true;
96
97
        $content = $contentService->createContent($contentCreate);
98
        /* END: Use Case */
99
100
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content', $content);
101
102
        return $content;
103
    }
104
105
    /**
106
     * Test for the createContent() method.
107
     *
108
     * Tests made for issue #EZP-20955 where Anonymous user is granted access to create content
109
     * and should have access to do that.
110
     *
111
     * @return \eZ\Publish\API\Repository\Values\Content\Content
112
     *
113
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
114
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentCreateStruct
115
     * @group user
116
     * @group field-type
117
     */
118
    public function testCreateContentAndPublishWithPrivilegedAnonymousUser()
119
    {
120
        if ($this->isVersion4()) {
121
            $this->markTestSkipped('This test requires eZ Publish 5');
122
        }
123
124
        $anonymousUserId = $this->generateId('user', 10);
125
126
        $repository = $this->getRepository();
127
        $contentService = $repository->getContentService();
128
        $contentTypeService = $repository->getContentTypeService();
129
        $locationService = $repository->getLocationService();
130
        $roleService = $repository->getRoleService();
131
132
        // Give Anonymous user role additional rights
133
        $role = $roleService->loadRoleByIdentifier('Anonymous');
134
        $roleDraft = $roleService->createRoleDraft($role);
135
        $policyCreateStruct = $roleService->newPolicyCreateStruct('content', 'create');
136
        $policyCreateStruct->addLimitation(new SectionLimitation(['limitationValues' => [1]]));
137
        $policyCreateStruct->addLimitation(new LocationLimitation(['limitationValues' => [2]]));
138
        $policyCreateStruct->addLimitation(new ContentTypeLimitation(['limitationValues' => [1]]));
139
        $roleDraft = $roleService->addPolicyByRoleDraft($roleDraft, $policyCreateStruct);
140
141
        $policyCreateStruct = $roleService->newPolicyCreateStruct('content', 'publish');
142
        $policyCreateStruct->addLimitation(new SectionLimitation(['limitationValues' => [1]]));
143
        $policyCreateStruct->addLimitation(new LocationLimitation(['limitationValues' => [2]]));
144
        $policyCreateStruct->addLimitation(new ContentTypeLimitation(['limitationValues' => [1]]));
145
        $roleDraft = $roleService->addPolicyByRoleDraft($roleDraft, $policyCreateStruct);
146
        $roleService->publishRoleDraft($roleDraft);
147
148
        // Set Anonymous user as current
149
        $repository->getPermissionResolver()->setCurrentUserReference($repository->getUserService()->loadUser($anonymousUserId));
150
151
        // Create a new content object:
152
        $contentCreate = $contentService->newContentCreateStruct(
153
            $contentTypeService->loadContentTypeByIdentifier('folder'),
154
            'eng-GB'
155
        );
156
157
        $contentCreate->setField('name', 'Folder 1');
158
159
        $content = $contentService->createContent(
160
            $contentCreate,
161
            [$locationService->newLocationCreateStruct(2)]
162
        );
163
164
        $contentService->publishVersion(
165
            $content->getVersionInfo()
166
        );
167
    }
168
169
    /**
170
     * Test for the createContent() method.
171
     *
172
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
173
     *
174
     * @return \eZ\Publish\API\Repository\Values\Content\Content
175
     *
176
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
177
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
178
     */
179
    public function testCreateContentSetsContentInfo($content)
180
    {
181
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $content->contentInfo);
182
183
        return $content;
184
    }
185
186
    /**
187
     * Test for the createContent() method.
188
     *
189
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
190
     *
191
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
192
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentSetsContentInfo
193
     */
194
    public function testCreateContentSetsExpectedContentInfo($content)
195
    {
196
        $this->assertEquals(
197
            [
198
                $content->id,
199
                28, // id of content type "forum"
200
                true,
201
                1,
202
                'abcdef0123456789abcdef0123456789',
203
                'eng-US',
204
                $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
205
                false,
206
                null,
207
                // Main Location id for unpublished Content should be null
208
                null,
209
            ],
210
            [
211
                $content->contentInfo->id,
212
                $content->contentInfo->contentTypeId,
213
                $content->contentInfo->alwaysAvailable,
214
                $content->contentInfo->currentVersionNo,
215
                $content->contentInfo->remoteId,
216
                $content->contentInfo->mainLanguageCode,
217
                $content->contentInfo->ownerId,
218
                $content->contentInfo->published,
219
                $content->contentInfo->publishedDate,
220
                $content->contentInfo->mainLocationId,
221
            ]
222
        );
223
    }
224
225
    /**
226
     * Test for the createContent() method.
227
     *
228
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
229
     *
230
     * @return \eZ\Publish\API\Repository\Values\Content\Content
231
     *
232
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
233
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
234
     */
235
    public function testCreateContentSetsVersionInfo($content)
236
    {
237
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo', $content->getVersionInfo());
238
239
        return $content;
240
    }
241
242
    /**
243
     * Test for the createContent() method.
244
     *
245
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
246
     *
247
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
248
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentSetsVersionInfo
249
     */
250
    public function testCreateContentSetsExpectedVersionInfo($content)
251
    {
252
        $this->assertEquals(
253
            [
254
                'status' => VersionInfo::STATUS_DRAFT,
255
                'versionNo' => 1,
256
                'creatorId' => $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
257
                'initialLanguageCode' => 'eng-US',
258
            ],
259
            [
260
                'status' => $content->getVersionInfo()->status,
261
                'versionNo' => $content->getVersionInfo()->versionNo,
262
                'creatorId' => $content->getVersionInfo()->creatorId,
263
                'initialLanguageCode' => $content->getVersionInfo()->initialLanguageCode,
264
            ]
265
        );
266
        $this->assertTrue($content->getVersionInfo()->isDraft());
267
        $this->assertFalse($content->getVersionInfo()->isPublished());
268
        $this->assertFalse($content->getVersionInfo()->isArchived());
269
    }
270
271
    /**
272
     * Test for the createContent() method.
273
     *
274
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
275
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
276
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
277
     */
278
    public function testCreateContentThrowsInvalidArgumentException()
279
    {
280
        if ($this->isVersion4()) {
281
            $this->markTestSkipped('This test requires eZ Publish 5');
282
        }
283
284
        $repository = $this->getRepository();
285
286
        /* BEGIN: Use Case */
287
        $contentTypeService = $repository->getContentTypeService();
288
        $contentService = $repository->getContentService();
289
290
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
291
292
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
293
        $contentCreate1->setField('name', 'An awesome Sidelfingen forum');
294
295
        $contentCreate1->remoteId = 'abcdef0123456789abcdef0123456789';
296
        $contentCreate1->alwaysAvailable = true;
297
298
        $draft = $contentService->createContent($contentCreate1);
299
        $contentService->publishVersion($draft->versionInfo);
300
301
        $contentCreate2 = $contentService->newContentCreateStruct($contentType, 'eng-GB');
302
        $contentCreate2->setField('name', 'An awesome Bielefeld forum');
303
304
        $contentCreate2->remoteId = 'abcdef0123456789abcdef0123456789';
305
        $contentCreate2->alwaysAvailable = false;
306
307
        // This call will fail with an "InvalidArgumentException", because the
308
        // remoteId is already in use.
309
        $contentService->createContent($contentCreate2);
310
        /* END: Use Case */
311
    }
312
313
    /**
314
     * Test for the createContent() method.
315
     *
316
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
317
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
318
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
319
     */
320 View Code Duplication
    public function testCreateContentThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
321
    {
322
        $repository = $this->getRepository();
323
324
        /* BEGIN: Use Case */
325
        $contentTypeService = $repository->getContentTypeService();
326
        $contentService = $repository->getContentService();
327
328
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
329
330
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
331
        // The name field does only accept strings and null as its values
332
        $contentCreate->setField('name', new \stdClass());
333
334
        // Throws InvalidArgumentException since the name field is filled
335
        // improperly
336
        $draft = $contentService->createContent($contentCreate);
0 ignored issues
show
Unused Code introduced by
$draft is not used, you could remove the assignment.

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

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

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

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

Loading history...
337
        /* END: Use Case */
338
    }
339
340
    /**
341
     * Test for the createContent() method.
342
     *
343
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
344
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
345
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
346
     */
347
    public function testCreateContentThrowsContentFieldValidationException()
348
    {
349
        $repository = $this->getRepository();
350
351
        /* BEGIN: Use Case */
352
        $contentTypeService = $repository->getContentTypeService();
353
        $contentService = $repository->getContentService();
354
355
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
356
357
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
358
        $contentCreate1->setField('name', 'An awesome Sidelfingen folder');
359
        // Violates string length constraint
360
        $contentCreate1->setField('short_name', str_repeat('a', 200));
361
362
        // Throws ContentFieldValidationException, since short_name does not pass
363
        // validation of the string length validator
364
        $draft = $contentService->createContent($contentCreate1);
0 ignored issues
show
Unused Code introduced by
$draft is not used, you could remove the assignment.

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

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

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

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

Loading history...
365
        /* END: Use Case */
366
    }
367
368
    /**
369
     * Test for the createContent() method.
370
     *
371
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
372
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
373
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
374
     */
375 View Code Duplication
    public function testCreateContentRequiredFieldMissing()
376
    {
377
        $repository = $this->getRepository();
378
379
        /* BEGIN: Use Case */
380
        $contentTypeService = $repository->getContentTypeService();
381
        $contentService = $repository->getContentService();
382
383
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
384
385
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
386
        // Required field "name" is not set
387
388
        // Throws a ContentFieldValidationException, since a required field is
389
        // missing
390
        $draft = $contentService->createContent($contentCreate1);
0 ignored issues
show
Unused Code introduced by
$draft is not used, you could remove the assignment.

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

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

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

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

Loading history...
391
        /* END: Use Case */
392
    }
393
394
    /**
395
     * Test for the createContent() method.
396
     *
397
     * NOTE: We have bidirectional dependencies between the ContentService and
398
     * the LocationService, so that we cannot use PHPUnit's test dependencies
399
     * here.
400
     *
401
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
402
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
403
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationByRemoteId
404
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
405
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
406
     * @group user
407
     */
408
    public function testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately()
409
    {
410
        $repository = $this->getRepository();
411
412
        $locationService = $repository->getLocationService();
413
414
        /* BEGIN: Use Case */
415
        $draft = $this->createContentDraftVersion1();
0 ignored issues
show
Unused Code introduced by
$draft is not used, you could remove the assignment.

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

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

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

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

Loading history...
416
417
        // The location will not have been created, yet, so this throws an
418
        // exception
419
        $location = $locationService->loadLocationByRemoteId(
0 ignored issues
show
Unused Code introduced by
$location is not used, you could remove the assignment.

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

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

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

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

Loading history...
420
            '0123456789abcdef0123456789abcdef'
421
        );
422
        /* END: Use Case */
423
    }
424
425
    /**
426
     * Test for the createContent() method.
427
     *
428
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
429
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
430
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
431
     */
432
    public function testCreateContentThrowsInvalidArgumentExceptionWithLocationCreateParameter()
433
    {
434
        $repository = $this->getRepository();
435
436
        $parentLocationId = $this->generateId('location', 56);
437
        /* BEGIN: Use Case */
438
        // $parentLocationId is a valid location ID
439
440
        $contentService = $repository->getContentService();
441
        $contentTypeService = $repository->getContentTypeService();
442
        $locationService = $repository->getLocationService();
443
444
        // Load content type
445
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
446
447
        // Configure new locations
448
        $locationCreate1 = $locationService->newLocationCreateStruct($parentLocationId);
449
450
        $locationCreate1->priority = 23;
451
        $locationCreate1->hidden = true;
452
        $locationCreate1->remoteId = '0123456789abcdef0123456789aaaaaa';
453
        $locationCreate1->sortField = Location::SORT_FIELD_NODE_ID;
454
        $locationCreate1->sortOrder = Location::SORT_ORDER_DESC;
455
456
        $locationCreate2 = $locationService->newLocationCreateStruct($parentLocationId);
457
458
        $locationCreate2->priority = 42;
459
        $locationCreate2->hidden = true;
460
        $locationCreate2->remoteId = '0123456789abcdef0123456789bbbbbb';
461
        $locationCreate2->sortField = Location::SORT_FIELD_NODE_ID;
462
        $locationCreate2->sortOrder = Location::SORT_ORDER_DESC;
463
464
        // Configure new content object
465
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
466
467
        $contentCreate->setField('name', 'A awesome Sindelfingen forum');
468
        $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
469
        $contentCreate->alwaysAvailable = true;
470
471
        // Create new content object under the specified location
472
        $draft = $contentService->createContent(
473
            $contentCreate,
474
            [$locationCreate1]
475
        );
476
        $contentService->publishVersion($draft->versionInfo);
477
478
        // This call will fail with an "InvalidArgumentException", because the
479
        // Content remoteId already exists,
480
        $contentService->createContent(
481
            $contentCreate,
482
            [$locationCreate2]
483
        );
484
        /* END: Use Case */
485
    }
486
487
    /**
488
     * Test for the loadContentInfo() method.
489
     *
490
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
491
     * @group user
492
     */
493 View Code Duplication
    public function testLoadContentInfo()
494
    {
495
        $repository = $this->getRepository();
496
497
        $mediaFolderId = $this->generateId('object', 41);
498
        /* BEGIN: Use Case */
499
        $contentService = $repository->getContentService();
500
501
        // Load the ContentInfo for "Media" folder
502
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
503
        /* END: Use Case */
504
505
        $this->assertInstanceOf(
506
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo',
507
            $contentInfo
508
        );
509
510
        return $contentInfo;
511
    }
512
513
    /**
514
     * Test for the returned value of the loadContentInfo() method.
515
     *
516
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
517
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentInfo
518
     *
519
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
520
     */
521
    public function testLoadContentInfoSetsExpectedContentInfo(ContentInfo $contentInfo)
522
    {
523
        $this->assertPropertiesCorrectUnsorted(
524
            $this->getExpectedMediaContentInfoProperties(),
525
            $contentInfo
526
        );
527
    }
528
529
    /**
530
     * Test for the loadContentInfo() method.
531
     *
532
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
533
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
534
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
535
     */
536 View Code Duplication
    public function testLoadContentInfoThrowsNotFoundException()
537
    {
538
        $repository = $this->getRepository();
539
540
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
541
        /* BEGIN: Use Case */
542
        $contentService = $repository->getContentService();
543
544
        // This call will fail with a NotFoundException
545
        $contentService->loadContentInfo($nonExistentContentId);
546
        /* END: Use Case */
547
    }
548
549
    /**
550
     * Test for the loadContentInfoByRemoteId() method.
551
     *
552
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
553
     */
554
    public function testLoadContentInfoByRemoteId()
555
    {
556
        $repository = $this->getRepository();
557
558
        /* BEGIN: Use Case */
559
        $contentService = $repository->getContentService();
560
561
        // Load the ContentInfo for "Media" folder
562
        $contentInfo = $contentService->loadContentInfoByRemoteId('faaeb9be3bd98ed09f606fc16d144eca');
563
        /* END: Use Case */
564
565
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $contentInfo);
566
567
        return $contentInfo;
568
    }
569
570
    /**
571
     * Test for the returned value of the loadContentInfoByRemoteId() method.
572
     *
573
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
574
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId
575
     *
576
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
577
     */
578 View Code Duplication
    public function testLoadContentInfoByRemoteIdSetsExpectedContentInfo(ContentInfo $contentInfo)
579
    {
580
        $this->assertPropertiesCorrectUnsorted(
581
            [
582
                'id' => 10,
583
                'contentTypeId' => 4,
584
                'name' => 'Anonymous User',
585
                'sectionId' => 2,
586
                'currentVersionNo' => 2,
587
                'published' => true,
588
                'ownerId' => 14,
589
                'modificationDate' => $this->createDateTime(1072180405),
590
                'publishedDate' => $this->createDateTime(1033920665),
591
                'alwaysAvailable' => 1,
592
                'remoteId' => 'faaeb9be3bd98ed09f606fc16d144eca',
593
                'mainLanguageCode' => 'eng-US',
594
                'mainLocationId' => 45,
595
            ],
596
            $contentInfo
597
        );
598
    }
599
600
    /**
601
     * Test for the loadContentInfoByRemoteId() method.
602
     *
603
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
604
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
605
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
606
     */
607
    public function testLoadContentInfoByRemoteIdThrowsNotFoundException()
608
    {
609
        $repository = $this->getRepository();
610
611
        /* BEGIN: Use Case */
612
        $contentService = $repository->getContentService();
613
614
        // This call will fail with a NotFoundException
615
        $contentService->loadContentInfoByRemoteId('abcdefghijklmnopqrstuvwxyz0123456789');
616
        /* END: Use Case */
617
    }
618
619
    /**
620
     * Test for the loadVersionInfo() method.
621
     *
622
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo()
623
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
624
     * @group user
625
     */
626 View Code Duplication
    public function testLoadVersionInfo()
627
    {
628
        $repository = $this->getRepository();
629
630
        $mediaFolderId = $this->generateId('object', 41);
631
        /* BEGIN: Use Case */
632
        // $mediaFolderId contains the ID of the "Media" folder
633
634
        $contentService = $repository->getContentService();
635
636
        // Load the ContentInfo for "Media" folder
637
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
638
639
        // Now load the current version info of the "Media" folder
640
        $versionInfo = $contentService->loadVersionInfo($contentInfo);
641
        /* END: Use Case */
642
643
        $this->assertInstanceOf(
644
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo',
645
            $versionInfo
646
        );
647
    }
648
649
    /**
650
     * Test for the loadVersionInfoById() method.
651
     *
652
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
653
     */
654 View Code Duplication
    public function testLoadVersionInfoById()
655
    {
656
        $repository = $this->getRepository();
657
658
        $mediaFolderId = $this->generateId('object', 41);
659
        /* BEGIN: Use Case */
660
        // $mediaFolderId contains the ID of the "Media" folder
661
662
        $contentService = $repository->getContentService();
663
664
        // Load the VersionInfo for "Media" folder
665
        $versionInfo = $contentService->loadVersionInfoById($mediaFolderId);
666
        /* END: Use Case */
667
668
        $this->assertInstanceOf(
669
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo',
670
            $versionInfo
671
        );
672
673
        return $versionInfo;
674
    }
675
676
    /**
677
     * Test for the returned value of the loadVersionInfoById() method.
678
     *
679
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
680
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
681
     *
682
     * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo
683
     */
684
    public function testLoadVersionInfoByIdSetsExpectedVersionInfo(VersionInfo $versionInfo)
685
    {
686
        $this->assertPropertiesCorrect(
687
            [
688
                'names' => [
689
                    'eng-US' => 'Media',
690
                ],
691
                'contentInfo' => new ContentInfo($this->getExpectedMediaContentInfoProperties()),
692
                'id' => 472,
693
                'versionNo' => 1,
694
                'modificationDate' => $this->createDateTime(1060695457),
695
                'creatorId' => 14,
696
                'creationDate' => $this->createDateTime(1060695450),
697
                'status' => VersionInfo::STATUS_PUBLISHED,
698
                'initialLanguageCode' => 'eng-US',
699
                'languageCodes' => [
700
                    'eng-US',
701
                ],
702
            ],
703
            $versionInfo
704
        );
705
        $this->assertTrue($versionInfo->isPublished());
706
        $this->assertFalse($versionInfo->isDraft());
707
        $this->assertFalse($versionInfo->isArchived());
708
    }
709
710
    /**
711
     * Test for the loadVersionInfoById() method.
712
     *
713
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
714
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
715
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
716
     */
717 View Code Duplication
    public function testLoadVersionInfoByIdThrowsNotFoundException()
718
    {
719
        $repository = $this->getRepository();
720
721
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
722
        /* BEGIN: Use Case */
723
        $contentService = $repository->getContentService();
724
725
        // This call will fail with a "NotFoundException"
726
        $contentService->loadVersionInfoById($nonExistentContentId);
727
        /* END: Use Case */
728
    }
729
730
    /**
731
     * Test for the loadContentByContentInfo() method.
732
     *
733
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo()
734
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
735
     */
736 View Code Duplication
    public function testLoadContentByContentInfo()
737
    {
738
        $repository = $this->getRepository();
739
740
        $mediaFolderId = $this->generateId('object', 41);
741
        /* BEGIN: Use Case */
742
        // $mediaFolderId contains the ID of the "Media" folder
743
744
        $contentService = $repository->getContentService();
745
746
        // Load the ContentInfo for "Media" folder
747
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
748
749
        // Now load the current content version for the info instance
750
        $content = $contentService->loadContentByContentInfo($contentInfo);
751
        /* END: Use Case */
752
753
        $this->assertInstanceOf(
754
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
755
            $content
756
        );
757
    }
758
759
    /**
760
     * Test for the loadContentByVersionInfo() method.
761
     *
762
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo()
763
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
764
     */
765
    public function testLoadContentByVersionInfo()
766
    {
767
        $repository = $this->getRepository();
768
769
        $mediaFolderId = $this->generateId('object', 41);
770
        /* BEGIN: Use Case */
771
        // $mediaFolderId contains the ID of the "Media" folder
772
773
        $contentService = $repository->getContentService();
774
775
        // Load the ContentInfo for "Media" folder
776
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
777
778
        // Load the current VersionInfo
779
        $versionInfo = $contentService->loadVersionInfo($contentInfo);
780
781
        // Now load the current content version for the info instance
782
        $content = $contentService->loadContentByVersionInfo($versionInfo);
783
        /* END: Use Case */
784
785
        $this->assertInstanceOf(
786
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
787
            $content
788
        );
789
    }
790
791
    /**
792
     * Test for the loadContent() method.
793
     *
794
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
795
     * @group user
796
     * @group field-type
797
     */
798 View Code Duplication
    public function testLoadContent()
799
    {
800
        $repository = $this->getRepository();
801
802
        $mediaFolderId = $this->generateId('object', 41);
803
        /* BEGIN: Use Case */
804
        // $mediaFolderId contains the ID of the "Media" folder
805
806
        $contentService = $repository->getContentService();
807
808
        // Load the Content for "Media" folder, any language and current version
809
        $content = $contentService->loadContent($mediaFolderId);
810
        /* END: Use Case */
811
812
        $this->assertInstanceOf(
813
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
814
            $content
815
        );
816
    }
817
818
    /**
819
     * Test for the loadContent() method.
820
     *
821
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
822
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
823
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
824
     */
825 View Code Duplication
    public function testLoadContentThrowsNotFoundException()
826
    {
827
        $repository = $this->getRepository();
828
829
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
830
        /* BEGIN: Use Case */
831
        $contentService = $repository->getContentService();
832
833
        // This call will fail with a "NotFoundException"
834
        $contentService->loadContent($nonExistentContentId);
835
        /* END: Use Case */
836
    }
837
838
    /**
839
     * Data provider for testLoadContentByRemoteId().
840
     *
841
     * @return array
842
     */
843
    public function contentRemoteIdVersionLanguageProvider()
844
    {
845
        return [
846
            ['f5c88a2209584891056f987fd965b0ba', null, null],
847
            ['f5c88a2209584891056f987fd965b0ba', ['eng-US'], null],
848
            ['f5c88a2209584891056f987fd965b0ba', null, 1],
849
            ['f5c88a2209584891056f987fd965b0ba', ['eng-US'], 1],
850
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', null, null],
851
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', ['eng-US'], null],
852
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', null, 1],
853
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', ['eng-US'], 1],
854
        ];
855
    }
856
857
    /**
858
     * Test for the loadContentByRemoteId() method.
859
     *
860
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId
861
     * @dataProvider contentRemoteIdVersionLanguageProvider
862
     *
863
     * @param string $remoteId
864
     * @param array|null $languages
865
     * @param int $versionNo
866
     */
867
    public function testLoadContentByRemoteId($remoteId, $languages, $versionNo)
868
    {
869
        $repository = $this->getRepository();
870
871
        $contentService = $repository->getContentService();
872
873
        $content = $contentService->loadContentByRemoteId($remoteId, $languages, $versionNo);
874
875
        $this->assertInstanceOf(
876
            Content::class,
877
            $content
878
        );
879
880
        $this->assertEquals($remoteId, $content->contentInfo->remoteId);
881
        if ($languages !== null) {
882
            $this->assertEquals($languages, $content->getVersionInfo()->languageCodes);
883
        }
884
        $this->assertEquals($versionNo ?: 1, $content->getVersionInfo()->versionNo);
885
    }
886
887
    /**
888
     * Test for the loadContentByRemoteId() method.
889
     *
890
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId()
891
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
892
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
893
     */
894
    public function testLoadContentByRemoteIdThrowsNotFoundException()
895
    {
896
        $repository = $this->getRepository();
897
898
        /* BEGIN: Use Case */
899
        $contentService = $repository->getContentService();
900
901
        // This call will fail with a "NotFoundException", because no content
902
        // object exists for the given remoteId
903
        $contentService->loadContentByRemoteId('a1b1c1d1e1f1a2b2c2d2e2f2a3b3c3d3');
904
        /* END: Use Case */
905
    }
906
907
    /**
908
     * Test for the publishVersion() method.
909
     *
910
     * @return \eZ\Publish\API\Repository\Values\Content\Content
911
     *
912
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
913
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
914
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
915
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
916
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
917
     * @group user
918
     * @group field-type
919
     */
920
    public function testPublishVersion()
921
    {
922
        $time = time();
923
        /* BEGIN: Use Case */
924
        $content = $this->createContentVersion1();
925
        /* END: Use Case */
926
927
        $this->assertInstanceOf(Content::class, $content);
928
        $this->assertTrue($content->contentInfo->published);
929
        $this->assertEquals(VersionInfo::STATUS_PUBLISHED, $content->versionInfo->status);
930
        $this->assertGreaterThanOrEqual($time, $content->contentInfo->publishedDate->getTimestamp());
931
        $this->assertGreaterThanOrEqual($time, $content->contentInfo->modificationDate->getTimestamp());
932
        $this->assertTrue($content->versionInfo->isPublished());
933
        $this->assertFalse($content->versionInfo->isDraft());
934
        $this->assertFalse($content->versionInfo->isArchived());
935
936
        return $content;
937
    }
938
939
    /**
940
     * Test for the publishVersion() method.
941
     *
942
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
943
     *
944
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
945
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
946
     */
947
    public function testPublishVersionSetsExpectedContentInfo($content)
948
    {
949
        $this->assertEquals(
950
            [
951
                $content->id,
952
                true,
953
                1,
954
                'abcdef0123456789abcdef0123456789',
955
                'eng-US',
956
                $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
957
                true,
958
            ],
959
            [
960
                $content->contentInfo->id,
961
                $content->contentInfo->alwaysAvailable,
962
                $content->contentInfo->currentVersionNo,
963
                $content->contentInfo->remoteId,
964
                $content->contentInfo->mainLanguageCode,
965
                $content->contentInfo->ownerId,
966
                $content->contentInfo->published,
967
            ]
968
        );
969
970
        $this->assertNotNull($content->contentInfo->mainLocationId);
971
        $date = new \DateTime('1984/01/01');
972
        $this->assertGreaterThan(
973
            $date->getTimestamp(),
974
            $content->contentInfo->publishedDate->getTimestamp()
975
        );
976
    }
977
978
    /**
979
     * Test for the publishVersion() method.
980
     *
981
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
982
     *
983
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
984
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
985
     */
986
    public function testPublishVersionSetsExpectedVersionInfo($content)
987
    {
988
        $this->assertEquals(
989
            [
990
                $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
991
                'eng-US',
992
                VersionInfo::STATUS_PUBLISHED,
993
                1,
994
            ],
995
            [
996
                $content->getVersionInfo()->creatorId,
997
                $content->getVersionInfo()->initialLanguageCode,
998
                $content->getVersionInfo()->status,
999
                $content->getVersionInfo()->versionNo,
1000
            ]
1001
        );
1002
1003
        $date = new \DateTime('1984/01/01');
1004
        $this->assertGreaterThan(
1005
            $date->getTimestamp(),
1006
            $content->getVersionInfo()->modificationDate->getTimestamp()
1007
        );
1008
1009
        $this->assertNotNull($content->getVersionInfo()->modificationDate);
1010
        $this->assertTrue($content->getVersionInfo()->isPublished());
1011
        $this->assertFalse($content->getVersionInfo()->isDraft());
1012
        $this->assertFalse($content->getVersionInfo()->isArchived());
1013
    }
1014
1015
    /**
1016
     * Test for the publishVersion() method.
1017
     *
1018
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1019
     *
1020
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1021
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
1022
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1023
     */
1024
    public function testPublishVersionCreatesLocationsDefinedOnCreate()
1025
    {
1026
        $repository = $this->getRepository();
1027
1028
        /* BEGIN: Use Case */
1029
        $content = $this->createContentVersion1();
1030
        /* END: Use Case */
1031
1032
        $locationService = $repository->getLocationService();
1033
        $location = $locationService->loadLocationByRemoteId(
1034
            '0123456789abcdef0123456789abcdef'
1035
        );
1036
1037
        $this->assertEquals(
1038
            $location->getContentInfo(),
1039
            $content->getVersionInfo()->getContentInfo()
1040
        );
1041
1042
        return [$content, $location];
1043
    }
1044
1045
    /**
1046
     * Test for the publishVersion() method.
1047
     *
1048
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1049
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionCreatesLocationsDefinedOnCreate
1050
     */
1051
    public function testCreateContentWithLocationCreateParameterCreatesExpectedLocation(array $testData)
1052
    {
1053
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $content */
1054
        /** @var \eZ\Publish\API\Repository\Values\Content\Location $location */
1055
        list($content, $location) = $testData;
1056
1057
        $parentLocationId = $this->generateId('location', 56);
1058
        $parentLocation = $this->getRepository()->getLocationService()->loadLocation($parentLocationId);
1059
        $mainLocationId = $content->getVersionInfo()->getContentInfo()->mainLocationId;
1060
1061
        $this->assertPropertiesCorrect(
1062
            [
1063
                'id' => $mainLocationId,
1064
                'priority' => 23,
1065
                'hidden' => true,
1066
                'invisible' => true,
1067
                'remoteId' => '0123456789abcdef0123456789abcdef',
1068
                'parentLocationId' => $parentLocationId,
1069
                'pathString' => $parentLocation->pathString . $mainLocationId . '/',
1070
                'depth' => $parentLocation->depth + 1,
1071
                'sortField' => Location::SORT_FIELD_NODE_ID,
1072
                'sortOrder' => Location::SORT_ORDER_DESC,
1073
            ],
1074
            $location
1075
        );
1076
    }
1077
1078
    /**
1079
     * Test for the publishVersion() method.
1080
     *
1081
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1082
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
1083
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1084
     */
1085 View Code Duplication
    public function testPublishVersionThrowsBadStateException()
1086
    {
1087
        $repository = $this->getRepository();
1088
1089
        $contentService = $repository->getContentService();
1090
1091
        /* BEGIN: Use Case */
1092
        $draft = $this->createContentDraftVersion1();
1093
1094
        // Publish the content draft
1095
        $contentService->publishVersion($draft->getVersionInfo());
1096
1097
        // This call will fail with a "BadStateException", because the version
1098
        // is already published.
1099
        $contentService->publishVersion($draft->getVersionInfo());
1100
        /* END: Use Case */
1101
    }
1102
1103
    /**
1104
     * Test that publishVersion() does not affect publishedDate (assuming previous version exists).
1105
     *
1106
     * @covers \eZ\Publish\API\Repository\ContentService::publishVersion
1107
     */
1108
    public function testPublishVersionDoesNotChangePublishedDate()
1109
    {
1110
        $repository = $this->getRepository();
1111
1112
        $contentService = $repository->getContentService();
1113
1114
        $publishedContent = $this->createContentVersion1();
1115
1116
        // force timestamps to differ
1117
        sleep(1);
1118
1119
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
1120
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1121
        $contentUpdateStruct->setField('name', 'New name');
1122
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
1123
        $republishedContent = $contentService->publishVersion($contentDraft->versionInfo);
1124
1125
        $this->assertEquals(
1126
            $publishedContent->contentInfo->publishedDate->getTimestamp(),
1127
            $republishedContent->contentInfo->publishedDate->getTimestamp()
1128
        );
1129
        $this->assertGreaterThan(
1130
            $publishedContent->contentInfo->modificationDate->getTimestamp(),
1131
            $republishedContent->contentInfo->modificationDate->getTimestamp()
1132
        );
1133
    }
1134
1135
    /**
1136
     * Test for the createContentDraft() method.
1137
     *
1138
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1139
     *
1140
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1141
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1142
     * @group user
1143
     */
1144
    public function testCreateContentDraft()
1145
    {
1146
        $repository = $this->getRepository();
1147
1148
        $contentService = $repository->getContentService();
1149
1150
        /* BEGIN: Use Case */
1151
        $content = $this->createContentVersion1();
1152
1153
        // Now we create a new draft from the published content
1154
        $draftedContent = $contentService->createContentDraft($content->contentInfo);
1155
        /* END: Use Case */
1156
1157
        $this->assertInstanceOf(
1158
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1159
            $draftedContent
1160
        );
1161
1162
        return $draftedContent;
1163
    }
1164
1165
    /**
1166
     * Test for the createContentDraft() method.
1167
     *
1168
     * Test that editor has access to edit own draft.
1169
     * Note: Editors have access to version_read, which is needed to load content drafts.
1170
     *
1171
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1172
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1173
     * @group user
1174
     */
1175 View Code Duplication
    public function testCreateContentDraftAndLoadAccess()
1176
    {
1177
        $repository = $this->getRepository();
1178
1179
        /* BEGIN: Use Case */
1180
        $user = $this->createUserVersion1();
1181
1182
        // Set new editor as user
1183
        $repository->setCurrentUser($user);
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...
1184
1185
        // Create draft
1186
        $draft = $this->createContentDraftVersion1(2, 'folder');
1187
1188
        // Try to load the draft
1189
        $contentService = $repository->getContentService();
1190
        $loadedDraft = $contentService->loadContent($draft->id);
1191
1192
        /* END: Use Case */
1193
1194
        $this->assertEquals($draft->id, $loadedDraft->id);
1195
    }
1196
1197
    /**
1198
     * Test for the createContentDraft() method.
1199
     *
1200
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1201
     *
1202
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1203
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1204
     */
1205
    public function testCreateContentDraftSetsExpectedProperties($draft)
1206
    {
1207
        $this->assertEquals(
1208
            [
1209
                'fieldCount' => 2,
1210
                'relationCount' => 0,
1211
            ],
1212
            [
1213
                'fieldCount' => count($draft->getFields()),
1214
                'relationCount' => count($this->getRepository()->getContentService()->loadRelations($draft->getVersionInfo())),
1215
            ]
1216
        );
1217
    }
1218
1219
    /**
1220
     * Test for the createContentDraft() method.
1221
     *
1222
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1223
     *
1224
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1225
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1226
     */
1227
    public function testCreateContentDraftSetsContentInfo($draft)
1228
    {
1229
        $contentInfo = $draft->contentInfo;
1230
1231
        $this->assertEquals(
1232
            [
1233
                $draft->id,
1234
                true,
1235
                1,
1236
                'eng-US',
1237
                $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
1238
                'abcdef0123456789abcdef0123456789',
1239
                1,
1240
            ],
1241
            [
1242
                $contentInfo->id,
1243
                $contentInfo->alwaysAvailable,
1244
                $contentInfo->currentVersionNo,
1245
                $contentInfo->mainLanguageCode,
1246
                $contentInfo->ownerId,
1247
                $contentInfo->remoteId,
1248
                $contentInfo->sectionId,
1249
            ]
1250
        );
1251
    }
1252
1253
    /**
1254
     * Test for the createContentDraft() method.
1255
     *
1256
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1257
     *
1258
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1259
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1260
     */
1261
    public function testCreateContentDraftSetsVersionInfo($draft)
1262
    {
1263
        $versionInfo = $draft->getVersionInfo();
1264
1265
        $this->assertEquals(
1266
            [
1267
                'creatorId' => $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
1268
                'initialLanguageCode' => 'eng-US',
1269
                'languageCodes' => [0 => 'eng-US'],
1270
                'status' => VersionInfo::STATUS_DRAFT,
1271
                'versionNo' => 2,
1272
            ],
1273
            [
1274
                'creatorId' => $versionInfo->creatorId,
1275
                'initialLanguageCode' => $versionInfo->initialLanguageCode,
1276
                'languageCodes' => $versionInfo->languageCodes,
1277
                'status' => $versionInfo->status,
1278
                'versionNo' => $versionInfo->versionNo,
1279
            ]
1280
        );
1281
        $this->assertTrue($versionInfo->isDraft());
1282
        $this->assertFalse($versionInfo->isPublished());
1283
        $this->assertFalse($versionInfo->isArchived());
1284
    }
1285
1286
    /**
1287
     * Test for the createContentDraft() method.
1288
     *
1289
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1290
     *
1291
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1292
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1293
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
1294
     */
1295 View Code Duplication
    public function testCreateContentDraftLoadVersionInfoStillLoadsPublishedVersion($draft)
0 ignored issues
show
Unused Code introduced by
The parameter $draft 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...
1296
    {
1297
        $repository = $this->getRepository();
1298
1299
        $contentService = $repository->getContentService();
1300
1301
        /* BEGIN: Use Case */
1302
        $content = $this->createContentVersion1();
1303
1304
        // Now we create a new draft from the published content
1305
        $contentService->createContentDraft($content->contentInfo);
1306
1307
        // This call will still load the published version
1308
        $versionInfoPublished = $contentService->loadVersionInfo($content->contentInfo);
1309
        /* END: Use Case */
1310
1311
        $this->assertEquals(1, $versionInfoPublished->versionNo);
1312
    }
1313
1314
    /**
1315
     * Test for the createContentDraft() method.
1316
     *
1317
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1318
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
1319
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1320
     */
1321 View Code Duplication
    public function testCreateContentDraftLoadContentStillLoadsPublishedVersion()
1322
    {
1323
        $repository = $this->getRepository();
1324
1325
        $contentService = $repository->getContentService();
1326
1327
        /* BEGIN: Use Case */
1328
        $content = $this->createContentVersion1();
1329
1330
        // Now we create a new draft from the published content
1331
        $contentService->createContentDraft($content->contentInfo);
1332
1333
        // This call will still load the published content version
1334
        $contentPublished = $contentService->loadContent($content->id);
1335
        /* END: Use Case */
1336
1337
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1338
    }
1339
1340
    /**
1341
     * Test for the createContentDraft() method.
1342
     *
1343
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1344
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
1345
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1346
     */
1347 View Code Duplication
    public function testCreateContentDraftLoadContentByRemoteIdStillLoadsPublishedVersion()
1348
    {
1349
        $repository = $this->getRepository();
1350
1351
        $contentService = $repository->getContentService();
1352
1353
        /* BEGIN: Use Case */
1354
        $content = $this->createContentVersion1();
1355
1356
        // Now we create a new draft from the published content
1357
        $contentService->createContentDraft($content->contentInfo);
1358
1359
        // This call will still load the published content version
1360
        $contentPublished = $contentService->loadContentByRemoteId('abcdef0123456789abcdef0123456789');
1361
        /* END: Use Case */
1362
1363
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1364
    }
1365
1366
    /**
1367
     * Test for the createContentDraft() method.
1368
     *
1369
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1370
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
1371
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1372
     */
1373 View Code Duplication
    public function testCreateContentDraftLoadContentByContentInfoStillLoadsPublishedVersion()
1374
    {
1375
        $repository = $this->getRepository();
1376
1377
        $contentService = $repository->getContentService();
1378
1379
        /* BEGIN: Use Case */
1380
        $content = $this->createContentVersion1();
1381
1382
        // Now we create a new draft from the published content
1383
        $contentService->createContentDraft($content->contentInfo);
1384
1385
        // This call will still load the published content version
1386
        $contentPublished = $contentService->loadContentByContentInfo($content->contentInfo);
1387
        /* END: Use Case */
1388
1389
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1390
    }
1391
1392
    /**
1393
     * Test for the newContentUpdateStruct() method.
1394
     *
1395
     * @covers \eZ\Publish\API\Repository\ContentService::newContentUpdateStruct
1396
     * @group user
1397
     */
1398
    public function testNewContentUpdateStruct()
1399
    {
1400
        $repository = $this->getRepository();
1401
1402
        /* BEGIN: Use Case */
1403
        $contentService = $repository->getContentService();
1404
1405
        $updateStruct = $contentService->newContentUpdateStruct();
1406
        /* END: Use Case */
1407
1408
        $this->assertInstanceOf(
1409
            ContentUpdateStruct::class,
1410
            $updateStruct
1411
        );
1412
1413
        $this->assertPropertiesCorrect(
1414
            [
1415
                'initialLanguageCode' => null,
1416
                'fields' => [],
1417
            ],
1418
            $updateStruct
1419
        );
1420
    }
1421
1422
    /**
1423
     * Test for the updateContent() method.
1424
     *
1425
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1426
     *
1427
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1428
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentUpdateStruct
1429
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1430
     * @group user
1431
     * @group field-type
1432
     */
1433
    public function testUpdateContent()
1434
    {
1435
        /* BEGIN: Use Case */
1436
        $draftVersion2 = $this->createUpdatedDraftVersion2();
1437
        /* END: Use Case */
1438
1439
        $this->assertInstanceOf(
1440
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1441
            $draftVersion2
1442
        );
1443
1444
        $this->assertEquals(
1445
            $this->generateId('user', 10),
1446
            $draftVersion2->versionInfo->creatorId,
1447
            'creatorId is not properly set on new Version'
1448
        );
1449
1450
        return $draftVersion2;
1451
    }
1452
1453
    /**
1454
     * Test for the updateContent_WithDifferentUser() method.
1455
     *
1456
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1457
     *
1458
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1459
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentUpdateStruct
1460
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1461
     * @group user
1462
     * @group field-type
1463
     */
1464
    public function testUpdateContentWithDifferentUser()
1465
    {
1466
        /* BEGIN: Use Case */
1467
        $arrayWithDraftVersion2 = $this->createUpdatedDraftVersion2NotAdmin();
1468
        /* END: Use Case */
1469
1470
        $this->assertInstanceOf(
1471
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1472
            $arrayWithDraftVersion2[0]
1473
        );
1474
1475
        $this->assertEquals(
1476
            $this->generateId('user', $arrayWithDraftVersion2[1]),
1477
            $arrayWithDraftVersion2[0]->versionInfo->creatorId,
1478
            'creatorId is not properly set on new Version'
1479
        );
1480
1481
        return $arrayWithDraftVersion2[0];
1482
    }
1483
1484
    /**
1485
     * Test for the updateContent() method.
1486
     *
1487
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1488
     *
1489
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1490
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1491
     */
1492
    public function testUpdateContentSetsExpectedFields($content)
1493
    {
1494
        $actual = $this->normalizeFields($content->getFields());
1495
1496
        $expected = [
1497
            new Field(
1498
                [
1499
                    'id' => 0,
1500
                    'value' => true,
1501
                    'languageCode' => 'eng-GB',
1502
                    'fieldDefIdentifier' => 'description',
1503
                    'fieldTypeIdentifier' => 'ezrichtext',
1504
                ]
1505
            ),
1506
            new Field(
1507
                [
1508
                    'id' => 0,
1509
                    'value' => true,
1510
                    'languageCode' => 'eng-US',
1511
                    'fieldDefIdentifier' => 'description',
1512
                    'fieldTypeIdentifier' => 'ezrichtext',
1513
                ]
1514
            ),
1515
            new Field(
1516
                [
1517
                    'id' => 0,
1518
                    'value' => true,
1519
                    'languageCode' => 'eng-GB',
1520
                    'fieldDefIdentifier' => 'name',
1521
                    'fieldTypeIdentifier' => 'ezstring',
1522
                ]
1523
            ),
1524
            new Field(
1525
                [
1526
                    'id' => 0,
1527
                    'value' => true,
1528
                    'languageCode' => 'eng-US',
1529
                    'fieldDefIdentifier' => 'name',
1530
                    'fieldTypeIdentifier' => 'ezstring',
1531
                ]
1532
            ),
1533
        ];
1534
1535
        $this->assertEquals($expected, $actual);
1536
    }
1537
1538
    /**
1539
     * Test for the updateContent() method.
1540
     *
1541
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1542
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
1543
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1544
     */
1545 View Code Duplication
    public function testUpdateContentThrowsBadStateException()
1546
    {
1547
        $repository = $this->getRepository();
1548
1549
        $contentService = $repository->getContentService();
1550
1551
        /* BEGIN: Use Case */
1552
        $content = $this->createContentVersion1();
1553
1554
        // Now create an update struct and modify some fields
1555
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1556
        $contentUpdateStruct->setField('title', 'An awesome² story about ezp.');
1557
        $contentUpdateStruct->setField('title', 'An awesome²³ story about ezp.', 'eng-GB');
1558
1559
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1560
1561
        // This call will fail with a "BadStateException", because $publishedContent
1562
        // is not a draft.
1563
        $contentService->updateContent(
1564
            $content->getVersionInfo(),
1565
            $contentUpdateStruct
1566
        );
1567
        /* END: Use Case */
1568
    }
1569
1570
    /**
1571
     * Test for the updateContent() method.
1572
     *
1573
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1574
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1575
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1576
     */
1577 View Code Duplication
    public function testUpdateContentThrowsInvalidArgumentExceptionWhenFieldTypeDoesNotAccept()
1578
    {
1579
        $repository = $this->getRepository();
1580
1581
        $contentService = $repository->getContentService();
1582
1583
        /* BEGIN: Use Case */
1584
        $draft = $this->createContentDraftVersion1();
1585
1586
        // Now create an update struct and modify some fields
1587
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1588
        // The name field does not accept a stdClass object as its input
1589
        $contentUpdateStruct->setField('name', new \stdClass(), 'eng-US');
1590
1591
        // Throws an InvalidArgumentException, since the value for field "name"
1592
        // is not accepted
1593
        $contentService->updateContent(
1594
            $draft->getVersionInfo(),
1595
            $contentUpdateStruct
1596
        );
1597
        /* END: Use Case */
1598
    }
1599
1600
    /**
1601
     * Test for the updateContent() method.
1602
     *
1603
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1604
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
1605
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1606
     */
1607 View Code Duplication
    public function testUpdateContentWhenMandatoryFieldIsEmpty()
1608
    {
1609
        $repository = $this->getRepository();
1610
1611
        $contentService = $repository->getContentService();
1612
1613
        /* BEGIN: Use Case */
1614
        $draft = $this->createContentDraftVersion1();
1615
1616
        // Now create an update struct and set a mandatory field to null
1617
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1618
        $contentUpdateStruct->setField('name', null);
1619
1620
        // Don't set this, then the above call without languageCode will fail
1621
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1622
1623
        // This call will fail with a "ContentFieldValidationException", because the
1624
        // mandatory "name" field is empty.
1625
        $contentService->updateContent(
1626
            $draft->getVersionInfo(),
1627
            $contentUpdateStruct
1628
        );
1629
        /* END: Use Case */
1630
    }
1631
1632
    /**
1633
     * Test for the updateContent() method.
1634
     *
1635
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1636
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
1637
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1638
     */
1639 View Code Duplication
    public function testUpdateContentThrowsContentFieldValidationException()
1640
    {
1641
        $repository = $this->getRepository();
1642
1643
        /* BEGIN: Use Case */
1644
        $contentTypeService = $repository->getContentTypeService();
1645
        $contentService = $repository->getContentService();
1646
1647
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1648
1649
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
1650
        $contentCreate->setField('name', 'An awesome Sidelfingen folder');
1651
1652
        $draft = $contentService->createContent($contentCreate);
1653
1654
        $contentUpdate = $contentService->newContentUpdateStruct();
1655
        // Violates string length constraint
1656
        $contentUpdate->setField('short_name', str_repeat('a', 200), 'eng-US');
1657
1658
        // Throws ContentFieldValidationException because the string length
1659
        // validation of the field "short_name" fails
1660
        $contentService->updateContent($draft->getVersionInfo(), $contentUpdate);
1661
        /* END: Use Case */
1662
    }
1663
1664
    /**
1665
     * Test for the updateContent() method.
1666
     *
1667
     * @covers \eZ\Publish\API\Repository\ContentService::updateContent()
1668
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1669
     */
1670
    public function testUpdateContentValidatorIgnoresRequiredFieldsOfNotUpdatedLanguages()
1671
    {
1672
        $repository = $this->getRepository();
1673
        /* BEGIN: Use Case */
1674
        $contentTypeService = $repository->getContentTypeService();
1675
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1676
1677
        // Create multilangual content
1678
        $contentService = $repository->getContentService();
1679
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
1680
        $contentCreate->setField('name', 'An awesome Sidelfingen folder', 'eng-US');
1681
        $contentCreate->setField('name', 'An awesome Sidelfingen folder', 'eng-GB');
1682
1683
        $contentDraft = $contentService->createContent($contentCreate);
1684
1685
        // 2. Update content type definition
1686
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1687
1688
        $fieldDefinition = $contentType->getFieldDefinition('description');
1689
        $fieldDefinitionUpdate = $contentTypeService->newFieldDefinitionUpdateStruct();
1690
        $fieldDefinitionUpdate->identifier = 'description';
1691
        $fieldDefinitionUpdate->isRequired = true;
1692
1693
        $contentTypeService->updateFieldDefinition(
1694
            $contentTypeDraft,
1695
            $fieldDefinition,
1696
            $fieldDefinitionUpdate
1697
        );
1698
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1699
1700
        // 3. Update only eng-US translation
1701
        $description = new DOMDocument();
1702
        $description->loadXML(<<<XML
1703
<?xml version="1.0" encoding="UTF-8"?>
1704
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ezxhtml="http://ez.no/xmlns/ezpublish/docbook/xhtml" xmlns:ezcustom="http://ez.no/xmlns/ezpublish/docbook/custom" version="5.0-variant ezpublish-1.0">
1705
    <para>Lorem ipsum dolor</para>
1706
</section>
1707
XML
1708
        );
1709
1710
        $contentUpdate = $contentService->newContentUpdateStruct();
1711
        $contentUpdate->setField('name', 'An awesome Sidelfingen folder (updated)', 'eng-US');
1712
        $contentUpdate->setField('description', $description);
1713
1714
        $contentService->updateContent($contentDraft->getVersionInfo(), $contentUpdate);
1715
        /* END: Use Case */
1716
    }
1717
1718
    /**
1719
     * Test for the updateContent() method.
1720
     *
1721
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1722
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1723
     */
1724
    public function testUpdateContentWithNotUpdatingMandatoryField()
1725
    {
1726
        $repository = $this->getRepository();
1727
1728
        $contentService = $repository->getContentService();
1729
1730
        /* BEGIN: Use Case */
1731
        $draft = $this->createContentDraftVersion1();
1732
1733
        // Now create an update struct which does not overwrite mandatory
1734
        // fields
1735
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1736
        $contentUpdateStruct->setField(
1737
            'description',
1738
            '<?xml version="1.0" encoding="UTF-8"?><section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0-variant ezpublish-1.0"/>'
1739
        );
1740
1741
        // Don't set this, then the above call without languageCode will fail
1742
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1743
1744
        // This will only update the "description" field in the "eng-US"
1745
        // language
1746
        $updatedDraft = $contentService->updateContent(
1747
            $draft->getVersionInfo(),
1748
            $contentUpdateStruct
1749
        );
1750
        /* END: Use Case */
1751
1752
        foreach ($updatedDraft->getFields() as $field) {
1753
            if ($field->languageCode === 'eng-US' && $field->fieldDefIdentifier === 'name' && $field->value !== null) {
1754
                // Found field
1755
                return;
1756
            }
1757
        }
1758
        $this->fail(
1759
            'Field with identifier "name" in language "eng-US" could not be found or has empty value.'
1760
        );
1761
    }
1762
1763
    /**
1764
     * Test for the createContentDraft() method.
1765
     *
1766
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft($contentInfo, $versionInfo)
1767
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1768
     */
1769 View Code Duplication
    public function testCreateContentDraftWithSecondParameter()
1770
    {
1771
        $repository = $this->getRepository();
1772
1773
        $contentService = $repository->getContentService();
1774
1775
        /* BEGIN: Use Case */
1776
        $contentVersion2 = $this->createContentVersion2();
1777
1778
        // Now we create a new draft from the initial version
1779
        $draftedContentReloaded = $contentService->createContentDraft(
1780
            $contentVersion2->contentInfo,
1781
            $contentVersion2->getVersionInfo()
1782
        );
1783
        /* END: Use Case */
1784
1785
        $this->assertEquals(3, $draftedContentReloaded->getVersionInfo()->versionNo);
1786
    }
1787
1788
    /**
1789
     * Test for the createContentDraft() method with third parameter.
1790
     *
1791
     * @covers \eZ\Publish\Core\Repository\ContentService::createContentDraft
1792
     */
1793 View Code Duplication
    public function testCreateContentDraftWithThirdParameter()
1794
    {
1795
        $repository = $this->getRepository();
1796
1797
        $contentService = $repository->getContentService();
1798
1799
        $content = $contentService->loadContent(4);
1800
        $user = $this->createUserVersion1();
1801
1802
        $draftContent = $contentService->createContentDraft(
1803
            $content->contentInfo,
1804
            $content->getVersionInfo(),
1805
            $user
1806
        );
1807
1808
        $this->assertInstanceOf(
1809
            Content::class,
1810
            $draftContent
1811
        );
1812
    }
1813
1814
    /**
1815
     * Test for the publishVersion() method.
1816
     *
1817
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1818
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1819
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1820
     */
1821 View Code Duplication
    public function testPublishVersionFromContentDraft()
1822
    {
1823
        $repository = $this->getRepository();
1824
1825
        $contentService = $repository->getContentService();
1826
1827
        /* BEGIN: Use Case */
1828
        $contentVersion2 = $this->createContentVersion2();
1829
        /* END: Use Case */
1830
1831
        $versionInfo = $contentService->loadVersionInfo($contentVersion2->contentInfo);
1832
1833
        $this->assertEquals(
1834
            [
1835
                'status' => VersionInfo::STATUS_PUBLISHED,
1836
                'versionNo' => 2,
1837
            ],
1838
            [
1839
                'status' => $versionInfo->status,
1840
                'versionNo' => $versionInfo->versionNo,
1841
            ]
1842
        );
1843
        $this->assertTrue($versionInfo->isPublished());
1844
        $this->assertFalse($versionInfo->isDraft());
1845
        $this->assertFalse($versionInfo->isArchived());
1846
    }
1847
1848
    /**
1849
     * Test for the publishVersion() method.
1850
     *
1851
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1852
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1853
     */
1854 View Code Duplication
    public function testPublishVersionFromContentDraftArchivesOldVersion()
1855
    {
1856
        $repository = $this->getRepository();
1857
1858
        $contentService = $repository->getContentService();
1859
1860
        /* BEGIN: Use Case */
1861
        $contentVersion2 = $this->createContentVersion2();
1862
        /* END: Use Case */
1863
1864
        $versionInfo = $contentService->loadVersionInfo($contentVersion2->contentInfo, 1);
1865
1866
        $this->assertEquals(
1867
            [
1868
                'status' => VersionInfo::STATUS_ARCHIVED,
1869
                'versionNo' => 1,
1870
            ],
1871
            [
1872
                'status' => $versionInfo->status,
1873
                'versionNo' => $versionInfo->versionNo,
1874
            ]
1875
        );
1876
        $this->assertTrue($versionInfo->isArchived());
1877
        $this->assertFalse($versionInfo->isDraft());
1878
        $this->assertFalse($versionInfo->isPublished());
1879
    }
1880
1881
    /**
1882
     * Test for the publishVersion() method.
1883
     *
1884
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1885
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1886
     */
1887
    public function testPublishVersionFromContentDraftUpdatesContentInfoCurrentVersion()
1888
    {
1889
        /* BEGIN: Use Case */
1890
        $contentVersion2 = $this->createContentVersion2();
1891
        /* END: Use Case */
1892
1893
        $this->assertEquals(2, $contentVersion2->contentInfo->currentVersionNo);
1894
    }
1895
1896
    /**
1897
     * Test for the publishVersion() method.
1898
     *
1899
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1900
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1901
     */
1902 View Code Duplication
    public function testPublishVersionFromOldContentDraftArchivesNewerVersionNo()
1903
    {
1904
        $repository = $this->getRepository();
1905
1906
        $contentService = $repository->getContentService();
1907
1908
        /* BEGIN: Use Case */
1909
        $content = $this->createContentVersion1();
1910
1911
        // Create a new draft with versionNo = 2
1912
        $draftedContentVersion2 = $contentService->createContentDraft($content->contentInfo);
1913
1914
        // Create another new draft with versionNo = 3
1915
        $draftedContentVersion3 = $contentService->createContentDraft($content->contentInfo);
1916
1917
        // Publish draft with versionNo = 3
1918
        $contentService->publishVersion($draftedContentVersion3->getVersionInfo());
1919
1920
        // Publish the first draft with versionNo = 2
1921
        // currentVersionNo is now 2, versionNo 3 will be archived
1922
        $publishedDraft = $contentService->publishVersion($draftedContentVersion2->getVersionInfo());
1923
        /* END: Use Case */
1924
1925
        $this->assertEquals(2, $publishedDraft->contentInfo->currentVersionNo);
1926
    }
1927
1928
    /**
1929
     * Test for the publishVersion() method, and that it creates limited archives.
1930
     *
1931
     * @todo Adapt this when per content type archive limited is added on repository Content Type model.
1932
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1933
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1934
     */
1935
    public function testPublishVersionNotCreatingUnlimitedArchives()
1936
    {
1937
        $repository = $this->getRepository();
1938
1939
        $contentService = $repository->getContentService();
1940
1941
        $content = $this->createContentVersion1();
1942
1943
        // Create a new draft with versionNo = 2
1944
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
1945
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
1946
1947
        // Create a new draft with versionNo = 3
1948
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
1949
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
1950
1951
        // Create a new draft with versionNo = 4
1952
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
1953
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
1954
1955
        // Create a new draft with versionNo = 5
1956
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
1957
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
1958
1959
        // Create a new draft with versionNo = 6
1960
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
1961
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
1962
1963
        // Create a new draft with versionNo = 7
1964
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
1965
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
1966
1967
        $versionInfoList = $contentService->loadVersions($content->contentInfo);
1968
1969
        $this->assertEquals(6, count($versionInfoList));
1970
        $this->assertEquals(2, $versionInfoList[0]->versionNo);
1971
        $this->assertEquals(7, $versionInfoList[5]->versionNo);
1972
1973
        $this->assertEquals(
1974
            [
1975
                VersionInfo::STATUS_ARCHIVED,
1976
                VersionInfo::STATUS_ARCHIVED,
1977
                VersionInfo::STATUS_ARCHIVED,
1978
                VersionInfo::STATUS_ARCHIVED,
1979
                VersionInfo::STATUS_ARCHIVED,
1980
                VersionInfo::STATUS_PUBLISHED,
1981
            ],
1982
            [
1983
                $versionInfoList[0]->status,
1984
                $versionInfoList[1]->status,
1985
                $versionInfoList[2]->status,
1986
                $versionInfoList[3]->status,
1987
                $versionInfoList[4]->status,
1988
                $versionInfoList[5]->status,
1989
            ]
1990
        );
1991
    }
1992
1993
    /**
1994
     * Test for the newContentMetadataUpdateStruct() method.
1995
     *
1996
     * @covers \eZ\Publish\API\Repository\ContentService::newContentMetadataUpdateStruct
1997
     * @group user
1998
     */
1999
    public function testNewContentMetadataUpdateStruct()
2000
    {
2001
        $repository = $this->getRepository();
2002
2003
        /* BEGIN: Use Case */
2004
        $contentService = $repository->getContentService();
2005
2006
        // Creates a new metadata update struct
2007
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2008
2009
        foreach ($metadataUpdate as $propertyName => $propertyValue) {
0 ignored issues
show
Bug introduced by
The expression $metadataUpdate of type object<eZ\Publish\API\Re...ntMetadataUpdateStruct> is not traversable.
Loading history...
2010
            $this->assertNull($propertyValue, "Property '{$propertyName}' initial value should be null'");
2011
        }
2012
2013
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
2014
        $metadataUpdate->mainLanguageCode = 'eng-GB';
2015
        $metadataUpdate->alwaysAvailable = false;
2016
        /* END: Use Case */
2017
2018
        $this->assertInstanceOf(
2019
            ContentMetadataUpdateStruct::class,
2020
            $metadataUpdate
2021
        );
2022
    }
2023
2024
    /**
2025
     * Test for the updateContentMetadata() method.
2026
     *
2027
     * @return \eZ\Publish\API\Repository\Values\Content\Content
2028
     *
2029
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2030
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
2031
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentMetadataUpdateStruct
2032
     * @group user
2033
     */
2034
    public function testUpdateContentMetadata()
2035
    {
2036
        $repository = $this->getRepository();
2037
2038
        $contentService = $repository->getContentService();
2039
2040
        /* BEGIN: Use Case */
2041
        $content = $this->createContentVersion1();
2042
2043
        // Creates a metadata update struct
2044
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2045
2046
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
2047
        $metadataUpdate->mainLanguageCode = 'eng-GB';
2048
        $metadataUpdate->alwaysAvailable = false;
2049
        $metadataUpdate->publishedDate = $this->createDateTime(441759600); // 1984/01/01
2050
        $metadataUpdate->modificationDate = $this->createDateTime(441759600); // 1984/01/01
2051
2052
        // Update the metadata of the published content object
2053
        $content = $contentService->updateContentMetadata(
2054
            $content->contentInfo,
2055
            $metadataUpdate
2056
        );
2057
        /* END: Use Case */
2058
2059
        $this->assertInstanceOf(
2060
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
2061
            $content
2062
        );
2063
2064
        return $content;
2065
    }
2066
2067
    /**
2068
     * Test for the updateContentMetadata() method.
2069
     *
2070
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
2071
     *
2072
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2073
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2074
     */
2075
    public function testUpdateContentMetadataSetsExpectedProperties($content)
2076
    {
2077
        $contentInfo = $content->contentInfo;
2078
2079
        $this->assertEquals(
2080
            [
2081
                'remoteId' => 'aaaabbbbccccddddeeeeffff11112222',
2082
                'sectionId' => $this->generateId('section', 1),
2083
                'alwaysAvailable' => false,
2084
                'currentVersionNo' => 1,
2085
                'mainLanguageCode' => 'eng-GB',
2086
                'modificationDate' => $this->createDateTime(441759600),
2087
                'ownerId' => $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
2088
                'published' => true,
2089
                'publishedDate' => $this->createDateTime(441759600),
2090
            ],
2091
            [
2092
                'remoteId' => $contentInfo->remoteId,
2093
                'sectionId' => $contentInfo->sectionId,
2094
                'alwaysAvailable' => $contentInfo->alwaysAvailable,
2095
                'currentVersionNo' => $contentInfo->currentVersionNo,
2096
                'mainLanguageCode' => $contentInfo->mainLanguageCode,
2097
                'modificationDate' => $contentInfo->modificationDate,
2098
                'ownerId' => $contentInfo->ownerId,
2099
                'published' => $contentInfo->published,
2100
                'publishedDate' => $contentInfo->publishedDate,
2101
            ]
2102
        );
2103
    }
2104
2105
    /**
2106
     * Test for the updateContentMetadata() method.
2107
     *
2108
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
2109
     *
2110
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2111
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2112
     */
2113
    public function testUpdateContentMetadataNotUpdatesContentVersion($content)
2114
    {
2115
        $this->assertEquals(1, $content->getVersionInfo()->versionNo);
2116
    }
2117
2118
    /**
2119
     * Test for the updateContentMetadata() method.
2120
     *
2121
     * @covers \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2122
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2123
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2124
     */
2125
    public function testUpdateContentMetadataThrowsInvalidArgumentExceptionOnDuplicateRemoteId()
2126
    {
2127
        $repository = $this->getRepository();
2128
2129
        $contentService = $repository->getContentService();
2130
2131
        /* BEGIN: Use Case */
2132
        // RemoteId of the "Media" page of an eZ Publish demo installation
2133
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2134
2135
        $content = $this->createContentVersion1();
2136
2137
        // Creates a metadata update struct
2138
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2139
        $metadataUpdate->remoteId = $mediaRemoteId;
2140
2141
        // This call will fail with an "InvalidArgumentException", because the
2142
        // specified remoteId is already used by the "Media" page.
2143
        $contentService->updateContentMetadata(
2144
            $content->contentInfo,
2145
            $metadataUpdate
2146
        );
2147
        /* END: Use Case */
2148
    }
2149
2150
    /**
2151
     * Test for the updateContentMetadata() method.
2152
     *
2153
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContentMetadata
2154
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2155
     */
2156
    public function testUpdateContentMetadataThrowsInvalidArgumentExceptionOnNoMetadataPropertiesSet()
2157
    {
2158
        $repository = $this->getRepository();
2159
2160
        $contentService = $repository->getContentService();
2161
2162
        $contentInfo = $contentService->loadContentInfo(4);
2163
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2164
2165
        // Throws an exception because no properties are set in $contentMetadataUpdateStruct
2166
        $contentService->updateContentMetadata($contentInfo, $contentMetadataUpdateStruct);
2167
    }
2168
2169
    /**
2170
     * @covers \eZ\Publish\API\Repository\ContentService::updateContentMetadata
2171
     *
2172
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
2173
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
2174
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
2175
     */
2176
    public function testUpdateContentAlwaysAvailable()
2177
    {
2178
        $repository = $this->getRepository();
2179
        $contentService = $repository->getContentService();
2180
2181
        $folder = $this->createFolder(['eng-GB' => 'Folder'], 2);
2182
2183
        $contentMetadataUpdate = $contentService->newContentMetadataUpdateStruct();
2184
        $contentMetadataUpdate->alwaysAvailable = !$folder->contentInfo->alwaysAvailable;
2185
        $contentService->updateContentMetadata($folder->contentInfo, $contentMetadataUpdate);
2186
2187
        $reloadedFolder = $contentService->loadContent($folder->id);
2188
        self::assertEquals(
2189
            $contentMetadataUpdate->alwaysAvailable,
2190
            $reloadedFolder->contentInfo->alwaysAvailable
2191
        );
2192
    }
2193
2194
    /**
2195
     * @covers \eZ\Publish\API\Repository\ContentService::updateContentMetadata
2196
     *
2197
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
2198
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
2199
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
2200
     */
2201
    public function testUpdateContentMainTranslation()
2202
    {
2203
        $repository = $this->getRepository();
2204
        $contentService = $repository->getContentService();
2205
        $locationService = $repository->getLocationService();
2206
2207
        // create a Content Type which is not always available by default
2208
        $contentType = $this->createContentType(
2209
            'test_t',
2210
            self::ENG_GB,
2211
            [
2212
                'name' => 'ezstring',
2213
            ],
2214
            false
2215
        );
2216
2217
        $contentCreate = $contentService->newContentCreateStruct(
2218
            $contentType,
2219
            self::ENG_US
2220
        );
2221
        $contentCreate->setField('name', 'My Content');
2222
        $content = $contentService->publishVersion(
2223
            $contentService->createContent(
2224
                $contentCreate,
2225
                [$locationService->newLocationCreateStruct(2)]
2226
            )->getVersionInfo()
2227
        );
2228
        // perform sanity check
2229
        self::assertFalse($content->contentInfo->alwaysAvailable);
2230
2231
        $updateStruct = $contentService->newContentMetadataUpdateStruct();
2232
        $updateStruct->mainLanguageCode = self::ENG_GB;
2233
2234
        $contentService->updateContentMetadata($content->contentInfo, $updateStruct);
2235
2236
        $reloadedContent = $contentService->loadContent($content->id);
2237
        self::assertEquals(self::ENG_GB, $reloadedContent->contentInfo->mainLanguageCode);
2238
2239
        // check that other properties remained unchanged
2240
        self::assertStructPropertiesCorrect(
2241
            $content->contentInfo,
2242
            $reloadedContent->contentInfo,
2243
            [
2244
                'id',
2245
                'contentTypeId',
2246
                'name',
2247
                'sectionId',
2248
                'currentVersionNo',
2249
                'published',
2250
                'ownerId',
2251
                'alwaysAvailable',
2252
                'remoteId',
2253
                'mainLocationId',
2254
                'status',
2255
            ]
2256
        );
2257
    }
2258
2259
    /**
2260
     * Test for the deleteContent() method.
2261
     *
2262
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
2263
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2264
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2265
     */
2266 View Code Duplication
    public function testDeleteContent()
2267
    {
2268
        $repository = $this->getRepository();
2269
2270
        $contentService = $repository->getContentService();
2271
        $locationService = $repository->getLocationService();
2272
2273
        /* BEGIN: Use Case */
2274
        $contentVersion2 = $this->createContentVersion2();
2275
2276
        // Load the locations for this content object
2277
        $locations = $locationService->loadLocations($contentVersion2->contentInfo);
2278
2279
        // This will delete the content, all versions and the associated locations
2280
        $contentService->deleteContent($contentVersion2->contentInfo);
2281
        /* END: Use Case */
2282
2283
        foreach ($locations as $location) {
2284
            $locationService->loadLocation($location->id);
2285
        }
2286
    }
2287
2288
    /**
2289
     * Test for the deleteContent() method.
2290
     *
2291
     * Test for issue EZP-21057:
2292
     * "contentService: Unable to delete a content with an empty file attribute"
2293
     *
2294
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
2295
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2296
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2297
     */
2298 View Code Duplication
    public function testDeleteContentWithEmptyBinaryField()
2299
    {
2300
        $repository = $this->getRepository();
2301
2302
        $contentService = $repository->getContentService();
2303
        $locationService = $repository->getLocationService();
2304
2305
        /* BEGIN: Use Case */
2306
        $contentVersion = $this->createContentVersion1EmptyBinaryField();
2307
2308
        // Load the locations for this content object
2309
        $locations = $locationService->loadLocations($contentVersion->contentInfo);
2310
2311
        // This will delete the content, all versions and the associated locations
2312
        $contentService->deleteContent($contentVersion->contentInfo);
2313
        /* END: Use Case */
2314
2315
        foreach ($locations as $location) {
2316
            $locationService->loadLocation($location->id);
2317
        }
2318
    }
2319
2320
    /**
2321
     * Test for the loadContentDrafts() method.
2322
     *
2323
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
2324
     */
2325
    public function testLoadContentDraftsReturnsEmptyArrayByDefault()
2326
    {
2327
        $repository = $this->getRepository();
2328
2329
        /* BEGIN: Use Case */
2330
        $contentService = $repository->getContentService();
2331
2332
        $contentDrafts = $contentService->loadContentDrafts();
2333
        /* END: Use Case */
2334
2335
        $this->assertSame([], $contentDrafts);
2336
    }
2337
2338
    /**
2339
     * Test for the loadContentDrafts() method.
2340
     *
2341
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
2342
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
2343
     */
2344
    public function testLoadContentDrafts()
2345
    {
2346
        $repository = $this->getRepository();
2347
2348
        /* BEGIN: Use Case */
2349
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
2350
        // of a eZ Publish demo installation.
2351
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2352
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
2353
2354
        $contentService = $repository->getContentService();
2355
2356
        // "Media" content object
2357
        $mediaContentInfo = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
2358
2359
        // "eZ Publish Demo Design ..." content object
2360
        $demoDesignContentInfo = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
2361
2362
        // Create some drafts
2363
        $contentService->createContentDraft($mediaContentInfo);
2364
        $contentService->createContentDraft($demoDesignContentInfo);
2365
2366
        // Now $contentDrafts should contain two drafted versions
2367
        $draftedVersions = $contentService->loadContentDrafts();
2368
        /* END: Use Case */
2369
2370
        $actual = [
2371
            $draftedVersions[0]->status,
2372
            $draftedVersions[0]->getContentInfo()->remoteId,
2373
            $draftedVersions[1]->status,
2374
            $draftedVersions[1]->getContentInfo()->remoteId,
2375
        ];
2376
        sort($actual, SORT_STRING);
2377
2378
        $this->assertEquals(
2379
            [
2380
                VersionInfo::STATUS_DRAFT,
2381
                VersionInfo::STATUS_DRAFT,
2382
                $demoDesignRemoteId,
2383
                $mediaRemoteId,
2384
            ],
2385
            $actual
2386
        );
2387
    }
2388
2389
    /**
2390
     * Test for the loadContentDrafts() method.
2391
     *
2392
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts($user)
2393
     */
2394
    public function testLoadContentDraftsWithFirstParameter()
2395
    {
2396
        $repository = $this->getRepository();
2397
2398
        /* BEGIN: Use Case */
2399
        $user = $this->createUserVersion1();
2400
2401
        // Get current user
2402
        $oldCurrentUser = $repository->getCurrentUser();
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
2403
2404
        // Set new editor as user
2405
        $repository->setCurrentUser($user);
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...
2406
2407
        // Remote id of the "Media" content object in an eZ Publish demo installation.
2408
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2409
2410
        $contentService = $repository->getContentService();
2411
2412
        // "Media" content object
2413
        $mediaContentInfo = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
2414
2415
        // Create a content draft
2416
        $contentService->createContentDraft($mediaContentInfo);
2417
2418
        // Reset to previous current user
2419
        $repository->setCurrentUser($oldCurrentUser);
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...
2420
2421
        // Now $contentDrafts for the previous current user and the new user
2422
        $newCurrentUserDrafts = $contentService->loadContentDrafts($user);
2423
        $oldCurrentUserDrafts = $contentService->loadContentDrafts($oldCurrentUser);
2424
        /* END: Use Case */
2425
2426
        $this->assertSame([], $oldCurrentUserDrafts);
2427
2428
        $this->assertEquals(
2429
            [
2430
                VersionInfo::STATUS_DRAFT,
2431
                $mediaRemoteId,
2432
            ],
2433
            [
2434
                $newCurrentUserDrafts[0]->status,
2435
                $newCurrentUserDrafts[0]->getContentInfo()->remoteId,
2436
            ]
2437
        );
2438
        $this->assertTrue($newCurrentUserDrafts[0]->isDraft());
2439
        $this->assertFalse($newCurrentUserDrafts[0]->isArchived());
2440
        $this->assertFalse($newCurrentUserDrafts[0]->isPublished());
2441
    }
2442
2443
    /**
2444
     * Test for the loadVersionInfo() method.
2445
     *
2446
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
2447
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2448
     */
2449
    public function testLoadVersionInfoWithSecondParameter()
2450
    {
2451
        $repository = $this->getRepository();
2452
2453
        $contentService = $repository->getContentService();
2454
2455
        /* BEGIN: Use Case */
2456
        $publishedContent = $this->createContentVersion1();
2457
2458
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
0 ignored issues
show
Unused Code introduced by
$draftContent is not used, you could remove the assignment.

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

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

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

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

Loading history...
2459
2460
        // Will return the VersionInfo of the $draftContent
2461
        $versionInfo = $contentService->loadVersionInfoById($publishedContent->id, 2);
2462
        /* END: Use Case */
2463
2464
        $this->assertEquals(2, $versionInfo->versionNo);
2465
2466
        // Check that ContentInfo contained in VersionInfo has correct main Location id set
2467
        $this->assertEquals(
2468
            $publishedContent->getVersionInfo()->getContentInfo()->mainLocationId,
2469
            $versionInfo->getContentInfo()->mainLocationId
2470
        );
2471
    }
2472
2473
    /**
2474
     * Test for the loadVersionInfo() method.
2475
     *
2476
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
2477
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2478
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
2479
     */
2480
    public function testLoadVersionInfoThrowsNotFoundExceptionWithSecondParameter()
2481
    {
2482
        $repository = $this->getRepository();
2483
2484
        $contentService = $repository->getContentService();
2485
2486
        /* BEGIN: Use Case */
2487
        $draft = $this->createContentDraftVersion1();
2488
2489
        // This call will fail with a "NotFoundException", because not versionNo
2490
        // 2 exists for this content object.
2491
        $contentService->loadVersionInfo($draft->contentInfo, 2);
2492
        /* END: Use Case */
2493
    }
2494
2495
    /**
2496
     * Test for the loadVersionInfoById() method.
2497
     *
2498
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
2499
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
2500
     */
2501
    public function testLoadVersionInfoByIdWithSecondParameter()
2502
    {
2503
        $repository = $this->getRepository();
2504
2505
        $contentService = $repository->getContentService();
2506
2507
        /* BEGIN: Use Case */
2508
        $publishedContent = $this->createContentVersion1();
2509
2510
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
2511
2512
        // Will return the VersionInfo of the $draftContent
2513
        $versionInfo = $contentService->loadVersionInfoById($publishedContent->id, 2);
2514
        /* END: Use Case */
2515
2516
        $this->assertEquals(2, $versionInfo->versionNo);
2517
2518
        // Check that ContentInfo contained in VersionInfo has correct main Location id set
2519
        $this->assertEquals(
2520
            $publishedContent->getVersionInfo()->getContentInfo()->mainLocationId,
2521
            $versionInfo->getContentInfo()->mainLocationId
2522
        );
2523
2524
        return [
2525
            'versionInfo' => $versionInfo,
2526
            'draftContent' => $draftContent,
2527
        ];
2528
    }
2529
2530
    /**
2531
     * Test for the returned value of the loadVersionInfoById() method.
2532
     *
2533
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoByIdWithSecondParameter
2534
     * @covers \eZ\Publish\API\Repository\ContentService::loadVersionInfoById
2535
     *
2536
     * @param array $data
2537
     */
2538
    public function testLoadVersionInfoByIdWithSecondParameterSetsExpectedVersionInfo(array $data)
2539
    {
2540
        /** @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo */
2541
        $versionInfo = $data['versionInfo'];
2542
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $draftContent */
2543
        $draftContent = $data['draftContent'];
2544
2545
        $this->assertPropertiesCorrect(
2546
            [
2547
                'names' => [
2548
                    'eng-US' => 'An awesome forum',
2549
                ],
2550
                'contentInfo' => new ContentInfo([
2551
                    'id' => $draftContent->contentInfo->id,
2552
                    'contentTypeId' => 28,
2553
                    'name' => 'An awesome forum',
2554
                    'sectionId' => 1,
2555
                    'currentVersionNo' => 1,
2556
                    'published' => true,
2557
                    'ownerId' => 14,
2558
                    // this Content Object is created at the test runtime
2559
                    'modificationDate' => $versionInfo->contentInfo->modificationDate,
2560
                    'publishedDate' => $versionInfo->contentInfo->publishedDate,
2561
                    'alwaysAvailable' => 1,
2562
                    'remoteId' => 'abcdef0123456789abcdef0123456789',
2563
                    'mainLanguageCode' => 'eng-US',
2564
                    'mainLocationId' => $draftContent->contentInfo->mainLocationId,
2565
                    'status' => ContentInfo::STATUS_PUBLISHED,
2566
                ]),
2567
                'id' => $draftContent->versionInfo->id,
2568
                'versionNo' => 2,
2569
                'creatorId' => 14,
2570
                'status' => 0,
2571
                'initialLanguageCode' => 'eng-US',
2572
                'languageCodes' => [
2573
                    'eng-US',
2574
                ],
2575
            ],
2576
            $versionInfo
2577
        );
2578
    }
2579
2580
    /**
2581
     * Test for the loadVersionInfoById() method.
2582
     *
2583
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
2584
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2585
     */
2586 View Code Duplication
    public function testLoadVersionInfoByIdThrowsNotFoundExceptionWithSecondParameter()
2587
    {
2588
        $repository = $this->getRepository();
2589
2590
        $contentService = $repository->getContentService();
2591
2592
        /* BEGIN: Use Case */
2593
        $content = $this->createContentVersion1();
2594
2595
        // This call will fail with a "NotFoundException", because not versionNo
2596
        // 2 exists for this content object.
2597
        $contentService->loadVersionInfoById($content->id, 2);
2598
        /* END: Use Case */
2599
    }
2600
2601
    /**
2602
     * Test for the loadContentByVersionInfo() method.
2603
     *
2604
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo($versionInfo, $languages)
2605
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
2606
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByVersionInfo
2607
     */
2608
    public function testLoadContentByVersionInfoWithSecondParameter()
2609
    {
2610
        $repository = $this->getRepository();
2611
2612
        $sectionId = $this->generateId('section', 1);
2613
        /* BEGIN: Use Case */
2614
        $contentTypeService = $repository->getContentTypeService();
2615
2616
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
2617
2618
        $contentService = $repository->getContentService();
2619
2620
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
2621
2622
        $contentCreateStruct->setField('name', 'Sindelfingen forum²');
2623
2624
        $contentCreateStruct->setField('name', 'Sindelfingen forum²³', 'eng-GB');
2625
2626
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
2627
        // $sectionId contains the ID of section 1
2628
        $contentCreateStruct->sectionId = $sectionId;
2629
        $contentCreateStruct->alwaysAvailable = true;
2630
2631
        // Create a new content draft
2632
        $content = $contentService->createContent($contentCreateStruct);
2633
2634
        // Now publish this draft
2635
        $publishedContent = $contentService->publishVersion($content->getVersionInfo());
2636
2637
        // Will return a content instance with fields in "eng-US"
2638
        $reloadedContent = $contentService->loadContentByVersionInfo(
2639
            $publishedContent->getVersionInfo(),
2640
            [
2641
                'eng-GB',
2642
            ],
2643
            false
2644
        );
2645
        /* END: Use Case */
2646
2647
        $actual = [];
2648 View Code Duplication
        foreach ($reloadedContent->getFields() as $field) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2649
            $actual[] = new Field(
2650
                [
2651
                    'id' => 0,
2652
                    'value' => ($field->value !== null ? true : null), // Actual value tested by FieldType integration tests
2653
                    'languageCode' => $field->languageCode,
2654
                    'fieldDefIdentifier' => $field->fieldDefIdentifier,
2655
                ]
2656
            );
2657
        }
2658
        usort(
2659
            $actual,
2660 View Code Duplication
            function ($field1, $field2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2661
                if (0 === ($return = strcasecmp($field1->fieldDefIdentifier, $field2->fieldDefIdentifier))) {
2662
                    return strcasecmp($field1->languageCode, $field2->languageCode);
2663
                }
2664
2665
                return $return;
2666
            }
2667
        );
2668
2669
        $expected = [
2670
            new Field(
2671
                [
2672
                    'id' => 0,
2673
                    'value' => true,
2674
                    'languageCode' => 'eng-GB',
2675
                    'fieldDefIdentifier' => 'description',
2676
                ]
2677
            ),
2678
            new Field(
2679
                [
2680
                    'id' => 0,
2681
                    'value' => true,
2682
                    'languageCode' => 'eng-GB',
2683
                    'fieldDefIdentifier' => 'name',
2684
                ]
2685
            ),
2686
        ];
2687
2688
        $this->assertEquals($expected, $actual);
2689
    }
2690
2691
    /**
2692
     * Test for the loadContentByContentInfo() method.
2693
     *
2694
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages)
2695
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
2696
     */
2697
    public function testLoadContentByContentInfoWithLanguageParameters()
2698
    {
2699
        $repository = $this->getRepository();
2700
2701
        $sectionId = $this->generateId('section', 1);
2702
        /* BEGIN: Use Case */
2703
        $contentTypeService = $repository->getContentTypeService();
2704
2705
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
2706
2707
        $contentService = $repository->getContentService();
2708
2709
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
2710
2711
        $contentCreateStruct->setField('name', 'Sindelfingen forum²');
2712
2713
        $contentCreateStruct->setField('name', 'Sindelfingen forum²³', 'eng-GB');
2714
2715
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
2716
        // $sectionId contains the ID of section 1
2717
        $contentCreateStruct->sectionId = $sectionId;
2718
        $contentCreateStruct->alwaysAvailable = true;
2719
2720
        // Create a new content draft
2721
        $content = $contentService->createContent($contentCreateStruct);
2722
2723
        // Now publish this draft
2724
        $publishedContent = $contentService->publishVersion($content->getVersionInfo());
2725
2726
        // Will return a content instance with fields in "eng-US"
2727
        $reloadedContent = $contentService->loadContentByContentInfo(
2728
            $publishedContent->contentInfo,
2729
            [
2730
                'eng-US',
2731
            ],
2732
            null,
2733
            false
2734
        );
2735
        /* END: Use Case */
2736
2737
        $actual = $this->normalizeFields($reloadedContent->getFields());
2738
2739
        $expected = [
2740
            new Field(
2741
                [
2742
                    'id' => 0,
2743
                    'value' => true,
2744
                    'languageCode' => 'eng-US',
2745
                    'fieldDefIdentifier' => 'description',
2746
                    'fieldTypeIdentifier' => 'ezrichtext',
2747
                ]
2748
            ),
2749
            new Field(
2750
                [
2751
                    'id' => 0,
2752
                    'value' => true,
2753
                    'languageCode' => 'eng-US',
2754
                    'fieldDefIdentifier' => 'name',
2755
                    'fieldTypeIdentifier' => 'ezstring',
2756
                ]
2757
            ),
2758
        ];
2759
2760
        $this->assertEquals($expected, $actual);
2761
2762
        // Will return a content instance with fields in "eng-GB" (versions prior to 6.0.0-beta9 returned "eng-US" also)
2763
        $reloadedContent = $contentService->loadContentByContentInfo(
2764
            $publishedContent->contentInfo,
2765
            [
2766
                'eng-GB',
2767
            ],
2768
            null,
2769
            true
2770
        );
2771
2772
        $actual = $this->normalizeFields($reloadedContent->getFields());
2773
2774
        $expected = [
2775
            new Field(
2776
                [
2777
                    'id' => 0,
2778
                    'value' => true,
2779
                    'languageCode' => 'eng-GB',
2780
                    'fieldDefIdentifier' => 'description',
2781
                    'fieldTypeIdentifier' => 'ezrichtext',
2782
                ]
2783
            ),
2784
            new Field(
2785
                [
2786
                    'id' => 0,
2787
                    'value' => true,
2788
                    'languageCode' => 'eng-GB',
2789
                    'fieldDefIdentifier' => 'name',
2790
                    'fieldTypeIdentifier' => 'ezstring',
2791
                ]
2792
            ),
2793
        ];
2794
2795
        $this->assertEquals($expected, $actual);
2796
2797
        // Will return a content instance with fields in main language "eng-US", as "fre-FR" does not exists
2798
        $reloadedContent = $contentService->loadContentByContentInfo(
2799
            $publishedContent->contentInfo,
2800
            [
2801
                'fre-FR',
2802
            ],
2803
            null,
2804
            true
2805
        );
2806
2807
        $actual = $this->normalizeFields($reloadedContent->getFields());
2808
2809
        $expected = [
2810
            new Field(
2811
                [
2812
                    'id' => 0,
2813
                    'value' => true,
2814
                    'languageCode' => 'eng-US',
2815
                    'fieldDefIdentifier' => 'description',
2816
                    'fieldTypeIdentifier' => 'ezrichtext',
2817
                ]
2818
            ),
2819
            new Field(
2820
                [
2821
                    'id' => 0,
2822
                    'value' => true,
2823
                    'languageCode' => 'eng-US',
2824
                    'fieldDefIdentifier' => 'name',
2825
                    'fieldTypeIdentifier' => 'ezstring',
2826
                ]
2827
            ),
2828
        ];
2829
2830
        $this->assertEquals($expected, $actual);
2831
    }
2832
2833
    /**
2834
     * Test for the loadContentByContentInfo() method.
2835
     *
2836
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
2837
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
2838
     */
2839 View Code Duplication
    public function testLoadContentByContentInfoWithVersionNumberParameter()
2840
    {
2841
        $repository = $this->getRepository();
2842
2843
        $contentService = $repository->getContentService();
2844
2845
        /* BEGIN: Use Case */
2846
        $publishedContent = $this->createContentVersion1();
2847
2848
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
0 ignored issues
show
Unused Code introduced by
$draftContent is not used, you could remove the assignment.

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

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

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

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

Loading history...
2849
2850
        // This content instance is identical to $draftContent
2851
        $draftContentReloaded = $contentService->loadContentByContentInfo(
2852
            $publishedContent->contentInfo,
2853
            null,
2854
            2
2855
        );
2856
        /* END: Use Case */
2857
2858
        $this->assertEquals(
2859
            2,
2860
            $draftContentReloaded->getVersionInfo()->versionNo
2861
        );
2862
2863
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
2864
        $this->assertEquals(
2865
            $publishedContent->versionInfo->contentInfo->mainLocationId,
2866
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
2867
        );
2868
    }
2869
2870
    /**
2871
     * Test for the loadContentByContentInfo() method.
2872
     *
2873
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
2874
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2875
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfoWithVersionNumberParameter
2876
     */
2877 View Code Duplication
    public function testLoadContentByContentInfoThrowsNotFoundExceptionWithVersionNumberParameter()
2878
    {
2879
        $repository = $this->getRepository();
2880
2881
        $contentService = $repository->getContentService();
2882
2883
        /* BEGIN: Use Case */
2884
        $content = $this->createContentVersion1();
2885
2886
        // This call will fail with a "NotFoundException", because no content
2887
        // with versionNo = 2 exists.
2888
        $contentService->loadContentByContentInfo($content->contentInfo, null, 2);
2889
        /* END: Use Case */
2890
    }
2891
2892
    /**
2893
     * Test for the loadContent() method.
2894
     *
2895
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages)
2896
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2897
     */
2898 View Code Duplication
    public function testLoadContentWithSecondParameter()
2899
    {
2900
        $repository = $this->getRepository();
2901
2902
        $contentService = $repository->getContentService();
2903
2904
        /* BEGIN: Use Case */
2905
        $draft = $this->createMultipleLanguageDraftVersion1();
2906
2907
        // This draft contains those fields localized with "eng-GB"
2908
        $draftLocalized = $contentService->loadContent($draft->id, ['eng-GB'], null, false);
2909
        /* END: Use Case */
2910
2911
        $this->assertLocaleFieldsEquals($draftLocalized->getFields(), 'eng-GB');
2912
2913
        return $draft;
2914
    }
2915
2916
    /**
2917
     * Test for the loadContent() method using undefined translation.
2918
     *
2919
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithSecondParameter
2920
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2921
     *
2922
     * @param \eZ\Publish\API\Repository\Values\Content\Content $contentDraft
2923
     */
2924
    public function testLoadContentWithSecondParameterThrowsNotFoundException(Content $contentDraft)
2925
    {
2926
        $repository = $this->getRepository();
2927
2928
        $contentService = $repository->getContentService();
2929
2930
        $contentService->loadContent($contentDraft->id, ['ger-DE'], null, false);
2931
    }
2932
2933
    /**
2934
     * Test for the loadContent() method.
2935
     *
2936
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
2937
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2938
     */
2939 View Code Duplication
    public function testLoadContentWithThirdParameter()
2940
    {
2941
        $repository = $this->getRepository();
2942
2943
        $contentService = $repository->getContentService();
2944
2945
        /* BEGIN: Use Case */
2946
        $publishedContent = $this->createContentVersion1();
2947
2948
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
0 ignored issues
show
Unused Code introduced by
$draftContent is not used, you could remove the assignment.

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

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

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

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

Loading history...
2949
2950
        // This content instance is identical to $draftContent
2951
        $draftContentReloaded = $contentService->loadContent($publishedContent->id, null, 2);
2952
        /* END: Use Case */
2953
2954
        $this->assertEquals(2, $draftContentReloaded->getVersionInfo()->versionNo);
2955
2956
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
2957
        $this->assertEquals(
2958
            $publishedContent->versionInfo->contentInfo->mainLocationId,
2959
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
2960
        );
2961
    }
2962
2963
    /**
2964
     * Test for the loadContent() method.
2965
     *
2966
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
2967
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2968
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithThirdParameter
2969
     */
2970 View Code Duplication
    public function testLoadContentThrowsNotFoundExceptionWithThirdParameter()
2971
    {
2972
        $repository = $this->getRepository();
2973
2974
        $contentService = $repository->getContentService();
2975
2976
        /* BEGIN: Use Case */
2977
        $content = $this->createContentVersion1();
2978
2979
        // This call will fail with a "NotFoundException", because for this
2980
        // content object no versionNo=2 exists.
2981
        $contentService->loadContent($content->id, null, 2);
2982
        /* END: Use Case */
2983
    }
2984
2985
    /**
2986
     * Test for the loadContentByRemoteId() method.
2987
     *
2988
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages)
2989
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2990
     */
2991 View Code Duplication
    public function testLoadContentByRemoteIdWithSecondParameter()
2992
    {
2993
        $repository = $this->getRepository();
2994
2995
        $contentService = $repository->getContentService();
2996
2997
        /* BEGIN: Use Case */
2998
        $draft = $this->createMultipleLanguageDraftVersion1();
2999
3000
        $contentService->publishVersion($draft->versionInfo);
3001
3002
        // This draft contains those fields localized with "eng-GB"
3003
        $draftLocalized = $contentService->loadContentByRemoteId(
3004
            $draft->contentInfo->remoteId,
3005
            ['eng-GB'],
3006
            null,
3007
            false
3008
        );
3009
        /* END: Use Case */
3010
3011
        $this->assertLocaleFieldsEquals($draftLocalized->getFields(), 'eng-GB');
3012
    }
3013
3014
    /**
3015
     * Test for the loadContentByRemoteId() method.
3016
     *
3017
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
3018
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3019
     */
3020 View Code Duplication
    public function testLoadContentByRemoteIdWithThirdParameter()
3021
    {
3022
        $repository = $this->getRepository();
3023
3024
        $contentService = $repository->getContentService();
3025
3026
        /* BEGIN: Use Case */
3027
        $publishedContent = $this->createContentVersion1();
3028
3029
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
0 ignored issues
show
Unused Code introduced by
$draftContent is not used, you could remove the assignment.

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

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

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

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

Loading history...
3030
3031
        // This content instance is identical to $draftContent
3032
        $draftContentReloaded = $contentService->loadContentByRemoteId(
3033
            $publishedContent->contentInfo->remoteId,
3034
            null,
3035
            2
3036
        );
3037
        /* END: Use Case */
3038
3039
        $this->assertEquals(2, $draftContentReloaded->getVersionInfo()->versionNo);
3040
3041
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
3042
        $this->assertEquals(
3043
            $publishedContent->versionInfo->contentInfo->mainLocationId,
3044
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
3045
        );
3046
    }
3047
3048
    /**
3049
     * Test for the loadContentByRemoteId() method.
3050
     *
3051
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
3052
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
3053
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteIdWithThirdParameter
3054
     */
3055
    public function testLoadContentByRemoteIdThrowsNotFoundExceptionWithThirdParameter()
3056
    {
3057
        $repository = $this->getRepository();
3058
3059
        $contentService = $repository->getContentService();
3060
3061
        /* BEGIN: Use Case */
3062
        $content = $this->createContentVersion1();
3063
3064
        // This call will fail with a "NotFoundException", because for this
3065
        // content object no versionNo=2 exists.
3066
        $contentService->loadContentByRemoteId(
3067
            $content->contentInfo->remoteId,
3068
            null,
3069
            2
3070
        );
3071
        /* END: Use Case */
3072
    }
3073
3074
    /**
3075
     * Test that retrieval of translated name field respects prioritized language list.
3076
     *
3077
     * @dataProvider getPrioritizedLanguageList
3078
     * @param string[]|null $languageCodes
3079
     */
3080
    public function testLoadContentWithPrioritizedLanguagesList($languageCodes)
3081
    {
3082
        $repository = $this->getRepository();
3083
3084
        $contentService = $repository->getContentService();
3085
3086
        $content = $this->createContentVersion2();
3087
3088
        $content = $contentService->loadContent($content->id, $languageCodes);
3089
3090
        $expectedName = $content->getVersionInfo()->getName(
3091
            isset($languageCodes[0]) ? $languageCodes[0] : null
3092
        );
3093
        $nameValue = $content->getFieldValue('name');
3094
        /** @var \eZ\Publish\Core\FieldType\TextLine\Value $nameValue */
3095
        self::assertEquals($expectedName, $nameValue->text);
3096
        self::assertEquals($expectedName, $content->getVersionInfo()->getName());
3097
        // Also check value on shortcut method on content
3098
        self::assertEquals($expectedName, $content->getName());
3099
    }
3100
3101
    /**
3102
     * @return array
3103
     */
3104
    public function getPrioritizedLanguageList()
3105
    {
3106
        return [
3107
            [['eng-US']],
3108
            [['eng-GB']],
3109
            [['eng-GB', 'eng-US']],
3110
            [['eng-US', 'eng-GB']],
3111
        ];
3112
    }
3113
3114
    /**
3115
     * Test for the deleteVersion() method.
3116
     *
3117
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3118
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3119
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3120
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3121
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
3122
     */
3123
    public function testDeleteVersion()
3124
    {
3125
        $repository = $this->getRepository();
3126
3127
        $contentService = $repository->getContentService();
3128
3129
        /* BEGIN: Use Case */
3130
        $content = $this->createContentVersion1();
3131
3132
        // Create new draft, because published or last version of the Content can't be deleted
3133
        $draft = $contentService->createContentDraft(
3134
            $content->getVersionInfo()->getContentInfo()
3135
        );
3136
3137
        // Delete the previously created draft
3138
        $contentService->deleteVersion($draft->getVersionInfo());
3139
        /* END: Use Case */
3140
3141
        $versions = $contentService->loadVersions($content->getVersionInfo()->getContentInfo());
3142
3143
        $this->assertCount(1, $versions);
3144
        $this->assertEquals(
3145
            $content->getVersionInfo()->id,
3146
            $versions[0]->id
3147
        );
3148
    }
3149
3150
    /**
3151
     * Test for the deleteVersion() method.
3152
     *
3153
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3154
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
3155
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3156
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3157
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3158
     */
3159
    public function testDeleteVersionThrowsBadStateExceptionOnPublishedVersion()
3160
    {
3161
        $repository = $this->getRepository();
3162
3163
        $contentService = $repository->getContentService();
3164
3165
        /* BEGIN: Use Case */
3166
        $content = $this->createContentVersion1();
3167
3168
        // This call will fail with a "BadStateException", because the content
3169
        // version is currently published.
3170
        $contentService->deleteVersion($content->getVersionInfo());
3171
        /* END: Use Case */
3172
    }
3173
3174
    /**
3175
     * Test for the deleteVersion() method.
3176
     *
3177
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3178
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
3179
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3180
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3181
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3182
     */
3183
    public function testDeleteVersionWorksIfOnlyVersionIsDraft()
3184
    {
3185
        $repository = $this->getRepository();
3186
3187
        $contentService = $repository->getContentService();
3188
3189
        /* BEGIN: Use Case */
3190
        $draft = $this->createContentDraftVersion1();
3191
3192
        $contentService->deleteVersion($draft->getVersionInfo());
3193
3194
        // This call will fail with a "NotFound", because we allow to delete content if remaining version is draft.
3195
        // Can normally only happen if there where always only a draft to begin with, simplifies UI edit API usage.
3196
        $contentService->loadContent($draft->id);
3197
        /* END: Use Case */
3198
    }
3199
3200
    /**
3201
     * Test for the loadVersions() method.
3202
     *
3203
     * @see \eZ\Publish\API\Repository\ContentService::loadVersions()
3204
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3205
     *
3206
     * @return \eZ\Publish\API\Repository\Values\Content\VersionInfo[]
3207
     */
3208
    public function testLoadVersions()
3209
    {
3210
        $repository = $this->getRepository();
3211
3212
        $contentService = $repository->getContentService();
3213
3214
        /* BEGIN: Use Case */
3215
        $contentVersion2 = $this->createContentVersion2();
3216
3217
        // Load versions of this ContentInfo instance
3218
        $versions = $contentService->loadVersions($contentVersion2->contentInfo);
3219
        /* END: Use Case */
3220
3221
        $expectedVersionsOrder = [
3222
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 1),
3223
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 2),
3224
        ];
3225
3226
        $this->assertEquals($expectedVersionsOrder, $versions);
3227
3228
        return $versions;
3229
    }
3230
3231
    /**
3232
     * Test for the loadVersions() method.
3233
     *
3234
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersions
3235
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersions
3236
     *
3237
     * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo[] $versions
3238
     */
3239
    public function testLoadVersionsSetsExpectedVersionInfo(array $versions)
3240
    {
3241
        $this->assertCount(2, $versions);
3242
3243
        $expectedVersions = [
3244
            [
3245
                'versionNo' => 1,
3246
                'creatorId' => 14,
3247
                'status' => VersionInfo::STATUS_ARCHIVED,
3248
                'initialLanguageCode' => 'eng-US',
3249
                'languageCodes' => ['eng-US'],
3250
            ],
3251
            [
3252
                'versionNo' => 2,
3253
                'creatorId' => 10,
3254
                'status' => VersionInfo::STATUS_PUBLISHED,
3255
                'initialLanguageCode' => 'eng-US',
3256
                'languageCodes' => ['eng-US', 'eng-GB'],
3257
            ],
3258
        ];
3259
3260
        $this->assertPropertiesCorrect($expectedVersions[0], $versions[0]);
3261
        $this->assertPropertiesCorrect($expectedVersions[1], $versions[1]);
3262
        $this->assertEquals(
3263
            $versions[0]->creationDate->getTimestamp(),
3264
            $versions[1]->creationDate->getTimestamp(),
3265
            'Creation time did not match within delta of 2 seconds',
3266
            2
3267
        );
3268
        $this->assertEquals(
3269
            $versions[0]->modificationDate->getTimestamp(),
3270
            $versions[1]->modificationDate->getTimestamp(),
3271
            'Creation time did not match within delta of 2 seconds',
3272
            2
3273
        );
3274
        $this->assertTrue($versions[0]->isArchived());
3275
        $this->assertFalse($versions[0]->isDraft());
3276
        $this->assertFalse($versions[0]->isPublished());
3277
3278
        $this->assertTrue($versions[1]->isPublished());
3279
        $this->assertFalse($versions[1]->isDraft());
3280
        $this->assertFalse($versions[1]->isArchived());
3281
    }
3282
3283
    /**
3284
     * Test for the copyContent() method.
3285
     *
3286
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
3287
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3288
     * @group field-type
3289
     */
3290 View Code Duplication
    public function testCopyContent()
3291
    {
3292
        $parentLocationId = $this->generateId('location', 56);
3293
3294
        $repository = $this->getRepository();
3295
3296
        $contentService = $repository->getContentService();
3297
        $locationService = $repository->getLocationService();
3298
3299
        /* BEGIN: Use Case */
3300
        $contentVersion2 = $this->createMultipleLanguageContentVersion2();
3301
3302
        // Configure new target location
3303
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3304
3305
        $targetLocationCreate->priority = 42;
3306
        $targetLocationCreate->hidden = true;
3307
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3308
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3309
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3310
3311
        // Copy content with all versions and drafts
3312
        $contentCopied = $contentService->copyContent(
3313
            $contentVersion2->contentInfo,
3314
            $targetLocationCreate
3315
        );
3316
        /* END: Use Case */
3317
3318
        $this->assertInstanceOf(
3319
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
3320
            $contentCopied
3321
        );
3322
3323
        $this->assertNotEquals(
3324
            $contentVersion2->contentInfo->remoteId,
3325
            $contentCopied->contentInfo->remoteId
3326
        );
3327
3328
        $this->assertNotEquals(
3329
            $contentVersion2->id,
3330
            $contentCopied->id
3331
        );
3332
3333
        $this->assertEquals(
3334
            2,
3335
            count($contentService->loadVersions($contentCopied->contentInfo))
3336
        );
3337
3338
        $this->assertEquals(2, $contentCopied->getVersionInfo()->versionNo);
3339
3340
        $this->assertAllFieldsEquals($contentCopied->getFields());
3341
3342
        $this->assertDefaultContentStates($contentCopied->contentInfo);
3343
3344
        $this->assertNotNull(
3345
            $contentCopied->contentInfo->mainLocationId,
3346
            'Expected main location to be set given we provided a LocationCreateStruct'
3347
        );
3348
    }
3349
3350
    /**
3351
     * Test for the copyContent() method with ezsettings.default.content.retain_owner_on_copy set to false
3352
     * See settings/test/integration_legacy.yml for service override.
3353
     *
3354
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
3355
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3356
     * @group field-type
3357
     */
3358
    public function testCopyContentWithNewOwner()
3359
    {
3360
        $parentLocationId = $this->generateId('location', 56);
3361
3362
        $repository = $this->getRepository();
3363
3364
        $contentService = $repository->getContentService();
3365
        $locationService = $repository->getLocationService();
3366
        $userService = $repository->getUserService();
3367
3368
        $newOwner = $this->createUser('new_owner', 'foo', 'bar');
3369
        /* BEGIN: Use Case */
3370
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $contentVersion2 */
3371
        $contentVersion2 = $this->createContentDraftVersion1(
3372
            $parentLocationId,
3373
            'forum',
3374
            'name',
3375
            $newOwner
3376
        );
3377
3378
        // Configure new target location
3379
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3380
3381
        $targetLocationCreate->priority = 42;
3382
        $targetLocationCreate->hidden = true;
3383
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3384
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3385
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3386
3387
        // Copy content with all versions and drafts
3388
        $contentCopied = $contentService->copyContent(
3389
            $contentVersion2->contentInfo,
3390
            $targetLocationCreate
3391
        );
3392
        /* END: Use Case */
3393
3394
        $this->assertEquals(
3395
            $newOwner->id,
3396
            $contentVersion2->contentInfo->ownerId
3397
        );
3398
        $this->assertEquals(
3399
            $userService->loadUserByLogin('admin')->getUserId(),
3400
            $contentCopied->contentInfo->ownerId
3401
        );
3402
    }
3403
3404
    /**
3405
     * Test for the copyContent() method.
3406
     *
3407
     * @see \eZ\Publish\API\Repository\ContentService::copyContent($contentInfo, $destinationLocationCreateStruct, $versionInfo)
3408
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
3409
     *
3410
     * @todo Fix to more descriptive name
3411
     */
3412 View Code Duplication
    public function testCopyContentWithThirdParameter()
3413
    {
3414
        $parentLocationId = $this->generateId('location', 56);
3415
3416
        $repository = $this->getRepository();
3417
3418
        $contentService = $repository->getContentService();
3419
        $locationService = $repository->getLocationService();
3420
3421
        /* BEGIN: Use Case */
3422
        $contentVersion2 = $this->createContentVersion2();
3423
3424
        // Configure new target location
3425
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3426
3427
        $targetLocationCreate->priority = 42;
3428
        $targetLocationCreate->hidden = true;
3429
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3430
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3431
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3432
3433
        // Copy only the initial version
3434
        $contentCopied = $contentService->copyContent(
3435
            $contentVersion2->contentInfo,
3436
            $targetLocationCreate,
3437
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 1)
3438
        );
3439
        /* END: Use Case */
3440
3441
        $this->assertInstanceOf(
3442
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
3443
            $contentCopied
3444
        );
3445
3446
        $this->assertNotEquals(
3447
            $contentVersion2->contentInfo->remoteId,
3448
            $contentCopied->contentInfo->remoteId
3449
        );
3450
3451
        $this->assertNotEquals(
3452
            $contentVersion2->id,
3453
            $contentCopied->id
3454
        );
3455
3456
        $this->assertEquals(
3457
            1,
3458
            count($contentService->loadVersions($contentCopied->contentInfo))
3459
        );
3460
3461
        $this->assertEquals(1, $contentCopied->getVersionInfo()->versionNo);
3462
3463
        $this->assertNotNull(
3464
            $contentCopied->contentInfo->mainLocationId,
3465
            'Expected main location to be set given we provided a LocationCreateStruct'
3466
        );
3467
    }
3468
3469
    /**
3470
     * Test for the addRelation() method.
3471
     *
3472
     * @return \eZ\Publish\API\Repository\Values\Content\Content
3473
     *
3474
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3475
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3476
     */
3477
    public function testAddRelation()
3478
    {
3479
        $repository = $this->getRepository();
3480
3481
        $contentService = $repository->getContentService();
3482
3483
        /* BEGIN: Use Case */
3484
        // RemoteId of the "Media" content of an eZ Publish demo installation
3485
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3486
3487
        $draft = $this->createContentDraftVersion1();
3488
3489
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3490
3491
        // Create relation between new content object and "Media" page
3492
        $relation = $contentService->addRelation(
3493
            $draft->getVersionInfo(),
3494
            $media
3495
        );
3496
        /* END: Use Case */
3497
3498
        $this->assertInstanceOf(
3499
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Relation',
3500
            $relation
3501
        );
3502
3503
        return $contentService->loadRelations($draft->getVersionInfo());
3504
    }
3505
3506
    /**
3507
     * Test for the addRelation() method.
3508
     *
3509
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3510
     *
3511
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3512
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3513
     */
3514
    public function testAddRelationAddsRelationToContent($relations)
3515
    {
3516
        $this->assertEquals(
3517
            1,
3518
            count($relations)
3519
        );
3520
    }
3521
3522
    /**
3523
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3524
     */
3525
    protected function assertExpectedRelations($relations)
3526
    {
3527
        $this->assertEquals(
3528
            [
3529
                'type' => Relation::COMMON,
3530
                'sourceFieldDefinitionIdentifier' => null,
3531
                'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3532
                'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3533
            ],
3534
            [
3535
                'type' => $relations[0]->type,
3536
                'sourceFieldDefinitionIdentifier' => $relations[0]->sourceFieldDefinitionIdentifier,
3537
                'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3538
                'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3539
            ]
3540
        );
3541
    }
3542
3543
    /**
3544
     * Test for the addRelation() method.
3545
     *
3546
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3547
     *
3548
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3549
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3550
     */
3551
    public function testAddRelationSetsExpectedRelations($relations)
3552
    {
3553
        $this->assertExpectedRelations($relations);
3554
    }
3555
3556
    /**
3557
     * Test for the createContentDraft() method.
3558
     *
3559
     * @return \eZ\Publish\API\Repository\Values\Content\Relation[]
3560
     *
3561
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
3562
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelationSetsExpectedRelations
3563
     */
3564
    public function testCreateContentDraftWithRelations()
3565
    {
3566
        $repository = $this->getRepository();
3567
3568
        $contentService = $repository->getContentService();
3569
3570
        // RemoteId of the "Media" content of an eZ Publish demo installation
3571
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3572
        $draft = $this->createContentDraftVersion1();
3573
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3574
3575
        // Create relation between new content object and "Media" page
3576
        $contentService->addRelation(
3577
            $draft->getVersionInfo(),
3578
            $media
3579
        );
3580
3581
        $content = $contentService->publishVersion($draft->versionInfo);
3582
        $newDraft = $contentService->createContentDraft($content->contentInfo);
3583
3584
        return $contentService->loadRelations($newDraft->getVersionInfo());
3585
    }
3586
3587
    /**
3588
     * Test for the createContentDraft() method.
3589
     *
3590
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3591
     *
3592
     * @return \eZ\Publish\API\Repository\Values\Content\Relation[]
3593
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithRelations
3594
     */
3595
    public function testCreateContentDraftWithRelationsCreatesRelations($relations)
3596
    {
3597
        $this->assertEquals(
3598
            1,
3599
            count($relations)
3600
        );
3601
3602
        return $relations;
3603
    }
3604
3605
    /**
3606
     * Test for the createContentDraft() method.
3607
     *
3608
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3609
     *
3610
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithRelationsCreatesRelations
3611
     */
3612
    public function testCreateContentDraftWithRelationsCreatesExpectedRelations($relations)
3613
    {
3614
        $this->assertExpectedRelations($relations);
3615
    }
3616
3617
    /**
3618
     * Test for the addRelation() method.
3619
     *
3620
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3621
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
3622
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3623
     */
3624 View Code Duplication
    public function testAddRelationThrowsBadStateException()
3625
    {
3626
        $repository = $this->getRepository();
3627
3628
        $contentService = $repository->getContentService();
3629
3630
        /* BEGIN: Use Case */
3631
        // RemoteId of the "Media" page of an eZ Publish demo installation
3632
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3633
3634
        $content = $this->createContentVersion1();
3635
3636
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3637
3638
        // This call will fail with a "BadStateException", because content is
3639
        // published and not a draft.
3640
        $contentService->addRelation(
3641
            $content->getVersionInfo(),
3642
            $media
3643
        );
3644
        /* END: Use Case */
3645
    }
3646
3647
    /**
3648
     * Test for the loadRelations() method.
3649
     *
3650
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3651
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3652
     */
3653
    public function testLoadRelations()
3654
    {
3655
        $repository = $this->getRepository();
3656
3657
        $contentService = $repository->getContentService();
3658
3659
        /* BEGIN: Use Case */
3660
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3661
        // of a eZ Publish demo installation.
3662
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3663
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3664
3665
        $draft = $this->createContentDraftVersion1();
3666
3667
        // Load other content objects
3668
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3669
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3670
3671
        // Create relation between new content object and "Media" page
3672
        $contentService->addRelation(
3673
            $draft->getVersionInfo(),
3674
            $media
3675
        );
3676
3677
        // Create another relation with the "Demo Design" page
3678
        $contentService->addRelation(
3679
            $draft->getVersionInfo(),
3680
            $demoDesign
3681
        );
3682
3683
        // Load all relations
3684
        $relations = $contentService->loadRelations($draft->getVersionInfo());
3685
        /* END: Use Case */
3686
3687
        usort(
3688
            $relations,
3689
            function ($rel1, $rel2) {
3690
                return strcasecmp(
3691
                    $rel2->getDestinationContentInfo()->remoteId,
3692
                    $rel1->getDestinationContentInfo()->remoteId
3693
                );
3694
            }
3695
        );
3696
3697
        $this->assertEquals(
3698
            [
3699
                [
3700
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3701
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3702
                ],
3703
                [
3704
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3705
                    'destinationContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3706
                ],
3707
            ],
3708
            [
3709
                [
3710
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3711
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3712
                ],
3713
                [
3714
                    'sourceContentInfo' => $relations[1]->sourceContentInfo->remoteId,
3715
                    'destinationContentInfo' => $relations[1]->destinationContentInfo->remoteId,
3716
                ],
3717
            ]
3718
        );
3719
    }
3720
3721
    /**
3722
     * Test for the loadRelations() method.
3723
     *
3724
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3725
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3726
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
3727
     */
3728
    public function testLoadRelationsSkipsArchivedContent()
3729
    {
3730
        $repository = $this->getRepository();
3731
3732
        $contentService = $repository->getContentService();
3733
3734
        /* BEGIN: Use Case */
3735
        $trashService = $repository->getTrashService();
3736
        $locationService = $repository->getLocationService();
3737
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3738
        // of a eZ Publish demo installation.
3739
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3740
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3741
3742
        $draft = $this->createContentDraftVersion1();
3743
3744
        // Load other content objects
3745
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3746
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3747
3748
        // Create relation between new content object and "Media" page
3749
        $contentService->addRelation(
3750
            $draft->getVersionInfo(),
3751
            $media
3752
        );
3753
3754
        // Create another relation with the "Demo Design" page
3755
        $contentService->addRelation(
3756
            $draft->getVersionInfo(),
3757
            $demoDesign
3758
        );
3759
3760
        $demoDesignLocation = $locationService->loadLocation($demoDesign->mainLocationId);
3761
3762
        // Trashing Content's last Location will change its status to archived,
3763
        // in this case relation towards it will not be loaded.
3764
        $trashService->trash($demoDesignLocation);
3765
3766
        // Load all relations
3767
        $relations = $contentService->loadRelations($draft->getVersionInfo());
3768
        /* END: Use Case */
3769
3770
        $this->assertCount(1, $relations);
3771
        $this->assertEquals(
3772
            [
3773
                [
3774
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3775
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3776
                ],
3777
            ],
3778
            [
3779
                [
3780
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3781
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3782
                ],
3783
            ]
3784
        );
3785
    }
3786
3787
    /**
3788
     * Test for the loadRelations() method.
3789
     *
3790
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3791
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3792
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
3793
     */
3794
    public function testLoadRelationsSkipsDraftContent()
3795
    {
3796
        $repository = $this->getRepository();
3797
3798
        $contentService = $repository->getContentService();
3799
3800
        /* BEGIN: Use Case */
3801
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3802
        // of a eZ Publish demo installation.
3803
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3804
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3805
3806
        $draft = $this->createContentDraftVersion1();
3807
3808
        // Load other content objects
3809
        $media = $contentService->loadContentByRemoteId($mediaRemoteId);
3810
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3811
3812
        // Create draft of "Media" page
3813
        $mediaDraft = $contentService->createContentDraft($media->contentInfo);
3814
3815
        // Create relation between "Media" page and new content object draft.
3816
        // This relation will not be loaded before the draft is published.
3817
        $contentService->addRelation(
3818
            $mediaDraft->getVersionInfo(),
3819
            $draft->getVersionInfo()->getContentInfo()
3820
        );
3821
3822
        // Create another relation with the "Demo Design" page
3823
        $contentService->addRelation(
3824
            $mediaDraft->getVersionInfo(),
3825
            $demoDesign
3826
        );
3827
3828
        // Load all relations
3829
        $relations = $contentService->loadRelations($mediaDraft->getVersionInfo());
3830
        /* END: Use Case */
3831
3832
        $this->assertCount(1, $relations);
3833
        $this->assertEquals(
3834
            [
3835
                [
3836
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3837
                    'destinationContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3838
                ],
3839
            ],
3840
            [
3841
                [
3842
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3843
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3844
                ],
3845
            ]
3846
        );
3847
    }
3848
3849
    /**
3850
     * Test for the loadReverseRelations() method.
3851
     *
3852
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
3853
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3854
     */
3855
    public function testLoadReverseRelations()
3856
    {
3857
        $repository = $this->getRepository();
3858
3859
        $contentService = $repository->getContentService();
3860
3861
        /* BEGIN: Use Case */
3862
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3863
        // of a eZ Publish demo installation.
3864
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3865
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3866
3867
        $versionInfo = $this->createContentVersion1()->getVersionInfo();
3868
        $contentInfo = $versionInfo->getContentInfo();
3869
3870
        // Create some drafts
3871
        $mediaDraft = $contentService->createContentDraft(
3872
            $contentService->loadContentInfoByRemoteId($mediaRemoteId)
3873
        );
3874
        $demoDesignDraft = $contentService->createContentDraft(
3875
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
3876
        );
3877
3878
        // Create relation between new content object and "Media" page
3879
        $relation1 = $contentService->addRelation(
3880
            $mediaDraft->getVersionInfo(),
3881
            $contentInfo
3882
        );
3883
3884
        // Create another relation with the "Demo Design" page
3885
        $relation2 = $contentService->addRelation(
3886
            $demoDesignDraft->getVersionInfo(),
3887
            $contentInfo
3888
        );
3889
3890
        // Publish drafts, so relations become active
3891
        $contentService->publishVersion($mediaDraft->getVersionInfo());
3892
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
3893
3894
        // Load all relations
3895
        $relations = $contentService->loadRelations($versionInfo);
3896
        $reverseRelations = $contentService->loadReverseRelations($contentInfo);
3897
        /* END: Use Case */
3898
3899
        $this->assertEquals($contentInfo->id, $relation1->getDestinationContentInfo()->id);
3900
        $this->assertEquals($mediaDraft->id, $relation1->getSourceContentInfo()->id);
3901
3902
        $this->assertEquals($contentInfo->id, $relation2->getDestinationContentInfo()->id);
3903
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
3904
3905
        $this->assertEquals(0, count($relations));
3906
        $this->assertEquals(2, count($reverseRelations));
3907
3908
        usort(
3909
            $reverseRelations,
3910
            function ($rel1, $rel2) {
3911
                return strcasecmp(
3912
                    $rel2->getSourceContentInfo()->remoteId,
3913
                    $rel1->getSourceContentInfo()->remoteId
3914
                );
3915
            }
3916
        );
3917
3918
        $this->assertEquals(
3919
            [
3920
                [
3921
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3922
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
3923
                ],
3924
                [
3925
                    'sourceContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3926
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
3927
                ],
3928
            ],
3929
            [
3930
                [
3931
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
3932
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
3933
                ],
3934
                [
3935
                    'sourceContentInfo' => $reverseRelations[1]->sourceContentInfo->remoteId,
3936
                    'destinationContentInfo' => $reverseRelations[1]->destinationContentInfo->remoteId,
3937
                ],
3938
            ]
3939
        );
3940
    }
3941
3942
    /**
3943
     * Test for the loadReverseRelations() method.
3944
     *
3945
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
3946
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3947
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
3948
     */
3949
    public function testLoadReverseRelationsSkipsArchivedContent()
3950
    {
3951
        $repository = $this->getRepository();
3952
3953
        $contentService = $repository->getContentService();
3954
3955
        /* BEGIN: Use Case */
3956
        $trashService = $repository->getTrashService();
3957
        $locationService = $repository->getLocationService();
3958
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3959
        // of a eZ Publish demo installation.
3960
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3961
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3962
3963
        $versionInfo = $this->createContentVersion1()->getVersionInfo();
3964
        $contentInfo = $versionInfo->getContentInfo();
3965
3966
        // Create some drafts
3967
        $mediaDraft = $contentService->createContentDraft(
3968
            $contentService->loadContentInfoByRemoteId($mediaRemoteId)
3969
        );
3970
        $demoDesignDraft = $contentService->createContentDraft(
3971
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
3972
        );
3973
3974
        // Create relation between new content object and "Media" page
3975
        $relation1 = $contentService->addRelation(
3976
            $mediaDraft->getVersionInfo(),
3977
            $contentInfo
3978
        );
3979
3980
        // Create another relation with the "Demo Design" page
3981
        $relation2 = $contentService->addRelation(
3982
            $demoDesignDraft->getVersionInfo(),
3983
            $contentInfo
3984
        );
3985
3986
        // Publish drafts, so relations become active
3987
        $contentService->publishVersion($mediaDraft->getVersionInfo());
3988
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
3989
3990
        $demoDesignLocation = $locationService->loadLocation($demoDesignDraft->contentInfo->mainLocationId);
3991
3992
        // Trashing Content's last Location will change its status to archived,
3993
        // in this case relation from it will not be loaded.
3994
        $trashService->trash($demoDesignLocation);
3995
3996
        // Load all relations
3997
        $relations = $contentService->loadRelations($versionInfo);
3998
        $reverseRelations = $contentService->loadReverseRelations($contentInfo);
3999
        /* END: Use Case */
4000
4001
        $this->assertEquals($contentInfo->id, $relation1->getDestinationContentInfo()->id);
4002
        $this->assertEquals($mediaDraft->id, $relation1->getSourceContentInfo()->id);
4003
4004
        $this->assertEquals($contentInfo->id, $relation2->getDestinationContentInfo()->id);
4005
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
4006
4007
        $this->assertEquals(0, count($relations));
4008
        $this->assertEquals(1, count($reverseRelations));
4009
4010
        $this->assertEquals(
4011
            [
4012
                [
4013
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
4014
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
4015
                ],
4016
            ],
4017
            [
4018
                [
4019
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
4020
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
4021
                ],
4022
            ]
4023
        );
4024
    }
4025
4026
    /**
4027
     * Test for the loadReverseRelations() method.
4028
     *
4029
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
4030
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
4031
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
4032
     */
4033
    public function testLoadReverseRelationsSkipsDraftContent()
4034
    {
4035
        $repository = $this->getRepository();
4036
4037
        $contentService = $repository->getContentService();
4038
4039
        /* BEGIN: Use Case */
4040
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
4041
        // of a eZ Publish demo installation.
4042
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4043
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
4044
4045
        // Load "Media" page Content
4046
        $media = $contentService->loadContentByRemoteId($mediaRemoteId);
4047
4048
        // Create some drafts
4049
        $newDraftVersionInfo = $this->createContentDraftVersion1()->getVersionInfo();
4050
        $demoDesignDraft = $contentService->createContentDraft(
4051
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
4052
        );
4053
4054
        // Create relation between "Media" page and new content object
4055
        $relation1 = $contentService->addRelation(
4056
            $newDraftVersionInfo,
4057
            $media->contentInfo
4058
        );
4059
4060
        // Create another relation with the "Demo Design" page
4061
        $relation2 = $contentService->addRelation(
4062
            $demoDesignDraft->getVersionInfo(),
4063
            $media->contentInfo
4064
        );
4065
4066
        // Publish drafts, so relations become active
4067
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
4068
        // We will not publish new Content draft, therefore relation from it
4069
        // will not be loaded as reverse relation for "Media" page
4070
        //$contentService->publishVersion( $newDraftVersionInfo );
4071
4072
        // Load all relations
4073
        $relations = $contentService->loadRelations($media->versionInfo);
4074
        $reverseRelations = $contentService->loadReverseRelations($media->contentInfo);
4075
        /* END: Use Case */
4076
4077
        $this->assertEquals($media->contentInfo->id, $relation1->getDestinationContentInfo()->id);
4078
        $this->assertEquals($newDraftVersionInfo->contentInfo->id, $relation1->getSourceContentInfo()->id);
4079
4080
        $this->assertEquals($media->contentInfo->id, $relation2->getDestinationContentInfo()->id);
4081
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
4082
4083
        $this->assertEquals(0, count($relations));
4084
        $this->assertEquals(1, count($reverseRelations));
4085
4086
        $this->assertEquals(
4087
            [
4088
                [
4089
                    'sourceContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
4090
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
4091
                ],
4092
            ],
4093
            [
4094
                [
4095
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
4096
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
4097
                ],
4098
            ]
4099
        );
4100
    }
4101
4102
    /**
4103
     * Test for the deleteRelation() method.
4104
     *
4105
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4106
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
4107
     */
4108
    public function testDeleteRelation()
4109
    {
4110
        $repository = $this->getRepository();
4111
4112
        $contentService = $repository->getContentService();
4113
4114
        /* BEGIN: Use Case */
4115
        // Remote ids of the "Media" and the "Demo Design" page of a eZ Publish
4116
        // demo installation.
4117
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4118
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
4119
4120
        $draft = $this->createContentDraftVersion1();
4121
4122
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4123
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
4124
4125
        // Establish some relations
4126
        $contentService->addRelation($draft->getVersionInfo(), $media);
4127
        $contentService->addRelation($draft->getVersionInfo(), $demoDesign);
4128
4129
        // Delete one of the currently created relations
4130
        $contentService->deleteRelation($draft->getVersionInfo(), $media);
4131
4132
        // The relations array now contains only one element
4133
        $relations = $contentService->loadRelations($draft->getVersionInfo());
4134
        /* END: Use Case */
4135
4136
        $this->assertEquals(1, count($relations));
4137
    }
4138
4139
    /**
4140
     * Test for the deleteRelation() method.
4141
     *
4142
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4143
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
4144
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
4145
     */
4146
    public function testDeleteRelationThrowsBadStateException()
4147
    {
4148
        $repository = $this->getRepository();
4149
4150
        $contentService = $repository->getContentService();
4151
4152
        /* BEGIN: Use Case */
4153
        // RemoteId of the "Media" page of an eZ Publish demo installation
4154
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4155
4156
        $content = $this->createContentVersion1();
4157
4158
        // Load the destination object
4159
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4160
4161
        // Create a new draft
4162
        $draftVersion2 = $contentService->createContentDraft($content->contentInfo);
4163
4164
        // Add a relation
4165
        $contentService->addRelation($draftVersion2->getVersionInfo(), $media);
4166
4167
        // Publish new version
4168
        $contentVersion2 = $contentService->publishVersion(
4169
            $draftVersion2->getVersionInfo()
4170
        );
4171
4172
        // This call will fail with a "BadStateException", because content is
4173
        // published and not a draft.
4174
        $contentService->deleteRelation(
4175
            $contentVersion2->getVersionInfo(),
4176
            $media
4177
        );
4178
        /* END: Use Case */
4179
    }
4180
4181
    /**
4182
     * Test for the deleteRelation() method.
4183
     *
4184
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4185
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
4186
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
4187
     */
4188 View Code Duplication
    public function testDeleteRelationThrowsInvalidArgumentException()
4189
    {
4190
        $repository = $this->getRepository();
4191
4192
        $contentService = $repository->getContentService();
4193
4194
        /* BEGIN: Use Case */
4195
        // RemoteId of the "Media" page of an eZ Publish demo installation
4196
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4197
4198
        $draft = $this->createContentDraftVersion1();
4199
4200
        // Load the destination object
4201
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4202
4203
        // This call will fail with a "InvalidArgumentException", because no
4204
        // relation exists between $draft and $media.
4205
        $contentService->deleteRelation(
4206
            $draft->getVersionInfo(),
4207
            $media
4208
        );
4209
        /* END: Use Case */
4210
    }
4211
4212
    /**
4213
     * Test for the createContent() method.
4214
     *
4215
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
4216
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4217
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4218
     */
4219
    public function testCreateContentInTransactionWithRollback()
4220
    {
4221
        if ($this->isVersion4()) {
4222
            $this->markTestSkipped('This test requires eZ Publish 5');
4223
        }
4224
4225
        $repository = $this->getRepository();
4226
4227
        /* BEGIN: Use Case */
4228
        $contentTypeService = $repository->getContentTypeService();
4229
        $contentService = $repository->getContentService();
4230
4231
        // Start a transaction
4232
        $repository->beginTransaction();
4233
4234
        try {
4235
            $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
4236
4237
            // Get a content create struct and set mandatory properties
4238
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
4239
            $contentCreate->setField('name', 'Sindelfingen forum');
4240
4241
            $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
4242
            $contentCreate->alwaysAvailable = true;
4243
4244
            // Create a new content object
4245
            $contentId = $contentService->createContent($contentCreate)->id;
4246
        } catch (Exception $e) {
4247
            // Cleanup hanging transaction on error
4248
            $repository->rollback();
4249
            throw $e;
4250
        }
4251
4252
        // Rollback all changes
4253
        $repository->rollback();
4254
4255
        try {
4256
            // This call will fail with a "NotFoundException"
4257
            $contentService->loadContent($contentId);
4258
        } catch (NotFoundException $e) {
4259
            // This is expected
4260
            return;
4261
        }
4262
        /* END: Use Case */
4263
4264
        $this->fail('Content object still exists after rollback.');
4265
    }
4266
4267
    /**
4268
     * Test for the createContent() method.
4269
     *
4270
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
4271
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4272
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4273
     */
4274
    public function testCreateContentInTransactionWithCommit()
4275
    {
4276
        if ($this->isVersion4()) {
4277
            $this->markTestSkipped('This test requires eZ Publish 5');
4278
        }
4279
4280
        $repository = $this->getRepository();
4281
4282
        /* BEGIN: Use Case */
4283
        $contentTypeService = $repository->getContentTypeService();
4284
        $contentService = $repository->getContentService();
4285
4286
        // Start a transaction
4287
        $repository->beginTransaction();
4288
4289
        try {
4290
            $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
4291
4292
            // Get a content create struct and set mandatory properties
4293
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
4294
            $contentCreate->setField('name', 'Sindelfingen forum');
4295
4296
            $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
4297
            $contentCreate->alwaysAvailable = true;
4298
4299
            // Create a new content object
4300
            $contentId = $contentService->createContent($contentCreate)->id;
4301
4302
            // Commit changes
4303
            $repository->commit();
4304
        } catch (Exception $e) {
4305
            // Cleanup hanging transaction on error
4306
            $repository->rollback();
4307
            throw $e;
4308
        }
4309
4310
        // Load the new content object
4311
        $content = $contentService->loadContent($contentId);
4312
        /* END: Use Case */
4313
4314
        $this->assertEquals($contentId, $content->id);
4315
    }
4316
4317
    /**
4318
     * Test for the createContent() method.
4319
     *
4320
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
4321
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
4322
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentThrowsNotFoundException
4323
     */
4324 View Code Duplication
    public function testCreateContentWithLocationCreateParameterInTransactionWithRollback()
4325
    {
4326
        $repository = $this->getRepository();
4327
4328
        $contentService = $repository->getContentService();
4329
4330
        /* BEGIN: Use Case */
4331
        // Start a transaction
4332
        $repository->beginTransaction();
4333
4334
        try {
4335
            $draft = $this->createContentDraftVersion1();
4336
        } catch (Exception $e) {
4337
            // Cleanup hanging transaction on error
4338
            $repository->rollback();
4339
            throw $e;
4340
        }
4341
4342
        $contentId = $draft->id;
4343
4344
        // Roleback the transaction
4345
        $repository->rollback();
4346
4347
        try {
4348
            // This call will fail with a "NotFoundException"
4349
            $contentService->loadContent($contentId);
4350
        } catch (NotFoundException $e) {
4351
            return;
4352
        }
4353
        /* END: Use Case */
4354
4355
        $this->fail('Can still load content object after rollback.');
4356
    }
4357
4358
    /**
4359
     * Test for the createContent() method.
4360
     *
4361
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
4362
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
4363
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentThrowsNotFoundException
4364
     */
4365 View Code Duplication
    public function testCreateContentWithLocationCreateParameterInTransactionWithCommit()
4366
    {
4367
        $repository = $this->getRepository();
4368
4369
        $contentService = $repository->getContentService();
4370
4371
        /* BEGIN: Use Case */
4372
        // Start a transaction
4373
        $repository->beginTransaction();
4374
4375
        try {
4376
            $draft = $this->createContentDraftVersion1();
4377
4378
            $contentId = $draft->id;
4379
4380
            // Roleback the transaction
4381
            $repository->commit();
4382
        } catch (Exception $e) {
4383
            // Cleanup hanging transaction on error
4384
            $repository->rollback();
4385
            throw $e;
4386
        }
4387
4388
        // Load the new content object
4389
        $content = $contentService->loadContent($contentId);
4390
        /* END: Use Case */
4391
4392
        $this->assertEquals($contentId, $content->id);
4393
    }
4394
4395
    /**
4396
     * Test for the createContentDraft() method.
4397
     *
4398
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
4399
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
4400
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4401
     */
4402
    public function testCreateContentDraftInTransactionWithRollback()
4403
    {
4404
        $repository = $this->getRepository();
4405
4406
        $contentId = $this->generateId('object', 12);
4407
        /* BEGIN: Use Case */
4408
        // $contentId is the ID of the "Administrator users" user group
4409
4410
        // Get the content service
4411
        $contentService = $repository->getContentService();
4412
4413
        // Load the user group content object
4414
        $content = $contentService->loadContent($contentId);
4415
4416
        // Start a new transaction
4417
        $repository->beginTransaction();
4418
4419
        try {
4420
            // Create a new draft
4421
            $drafted = $contentService->createContentDraft($content->contentInfo);
4422
4423
            // Store version number for later reuse
4424
            $versionNo = $drafted->versionInfo->versionNo;
4425
        } catch (Exception $e) {
4426
            // Cleanup hanging transaction on error
4427
            $repository->rollback();
4428
            throw $e;
4429
        }
4430
4431
        // Rollback
4432
        $repository->rollback();
4433
4434
        try {
4435
            // This call will fail with a "NotFoundException"
4436
            $contentService->loadContent($contentId, null, $versionNo);
4437
        } catch (NotFoundException $e) {
4438
            return;
4439
        }
4440
        /* END: Use Case */
4441
4442
        $this->fail('Can still load content draft after rollback');
4443
    }
4444
4445
    /**
4446
     * Test for the createContentDraft() method.
4447
     *
4448
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
4449
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
4450
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4451
     */
4452 View Code Duplication
    public function testCreateContentDraftInTransactionWithCommit()
4453
    {
4454
        $repository = $this->getRepository();
4455
4456
        $contentId = $this->generateId('object', 12);
4457
        /* BEGIN: Use Case */
4458
        // $contentId is the ID of the "Administrator users" user group
4459
4460
        // Get the content service
4461
        $contentService = $repository->getContentService();
4462
4463
        // Load the user group content object
4464
        $content = $contentService->loadContent($contentId);
4465
4466
        // Start a new transaction
4467
        $repository->beginTransaction();
4468
4469
        try {
4470
            // Create a new draft
4471
            $drafted = $contentService->createContentDraft($content->contentInfo);
4472
4473
            // Store version number for later reuse
4474
            $versionNo = $drafted->versionInfo->versionNo;
4475
4476
            // Commit all changes
4477
            $repository->commit();
4478
        } catch (Exception $e) {
4479
            // Cleanup hanging transaction on error
4480
            $repository->rollback();
4481
            throw $e;
4482
        }
4483
4484
        $content = $contentService->loadContent($contentId, null, $versionNo);
4485
        /* END: Use Case */
4486
4487
        $this->assertEquals(
4488
            $versionNo,
4489
            $content->getVersionInfo()->versionNo
4490
        );
4491
    }
4492
4493
    /**
4494
     * Test for the publishVersion() method.
4495
     *
4496
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
4497
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
4498
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4499
     */
4500 View Code Duplication
    public function testPublishVersionInTransactionWithRollback()
4501
    {
4502
        $repository = $this->getRepository();
4503
4504
        $contentId = $this->generateId('object', 12);
4505
        /* BEGIN: Use Case */
4506
        // $contentId is the ID of the "Administrator users" user group
4507
4508
        // Get the content service
4509
        $contentService = $repository->getContentService();
4510
4511
        // Load the user group content object
4512
        $content = $contentService->loadContent($contentId);
4513
4514
        // Start a new transaction
4515
        $repository->beginTransaction();
4516
4517
        try {
4518
            $draftVersion = $contentService->createContentDraft($content->contentInfo)->getVersionInfo();
4519
4520
            // Publish a new version
4521
            $content = $contentService->publishVersion($draftVersion);
4522
4523
            // Store version number for later reuse
4524
            $versionNo = $content->versionInfo->versionNo;
4525
        } catch (Exception $e) {
4526
            // Cleanup hanging transaction on error
4527
            $repository->rollback();
4528
            throw $e;
4529
        }
4530
4531
        // Rollback
4532
        $repository->rollback();
4533
4534
        try {
4535
            // This call will fail with a "NotFoundException"
4536
            $contentService->loadContent($contentId, null, $versionNo);
4537
        } catch (NotFoundException $e) {
4538
            return;
4539
        }
4540
        /* END: Use Case */
4541
4542
        $this->fail('Can still load content draft after rollback');
4543
    }
4544
4545
    /**
4546
     * Test for the publishVersion() method.
4547
     *
4548
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
4549
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
4550
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
4551
     */
4552 View Code Duplication
    public function testPublishVersionInTransactionWithCommit()
4553
    {
4554
        $repository = $this->getRepository();
4555
4556
        /* BEGIN: Use Case */
4557
        // ID of the "Administrator users" user group
4558
        $contentId = 12;
4559
4560
        // Get the content service
4561
        $contentService = $repository->getContentService();
4562
4563
        // Load the user group content object
4564
        $template = $contentService->loadContent($contentId);
4565
4566
        // Start a new transaction
4567
        $repository->beginTransaction();
4568
4569
        try {
4570
            // Publish a new version
4571
            $content = $contentService->publishVersion(
4572
                $contentService->createContentDraft($template->contentInfo)->getVersionInfo()
4573
            );
4574
4575
            // Store version number for later reuse
4576
            $versionNo = $content->versionInfo->versionNo;
4577
4578
            // Commit all changes
4579
            $repository->commit();
4580
        } catch (Exception $e) {
4581
            // Cleanup hanging transaction on error
4582
            $repository->rollback();
4583
            throw $e;
4584
        }
4585
4586
        // Load current version info
4587
        $versionInfo = $contentService->loadVersionInfo($content->contentInfo);
4588
        /* END: Use Case */
4589
4590
        $this->assertEquals($versionNo, $versionInfo->versionNo);
4591
    }
4592
4593
    /**
4594
     * Test for the updateContent() method.
4595
     *
4596
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
4597
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
4598
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4599
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4600
     */
4601 View Code Duplication
    public function testUpdateContentInTransactionWithRollback()
4602
    {
4603
        $repository = $this->getRepository();
4604
4605
        $contentId = $this->generateId('object', 12);
4606
        /* BEGIN: Use Case */
4607
        // $contentId is the ID of the "Administrator users" user group
4608
4609
        // Load content service
4610
        $contentService = $repository->getContentService();
4611
4612
        // Create a new user group draft
4613
        $draft = $contentService->createContentDraft(
4614
            $contentService->loadContentInfo($contentId)
4615
        );
4616
4617
        // Get an update struct and change the group name
4618
        $contentUpdate = $contentService->newContentUpdateStruct();
4619
        $contentUpdate->setField('name', 'Administrators', 'eng-US');
4620
4621
        // Start a transaction
4622
        $repository->beginTransaction();
4623
4624
        try {
4625
            // Update the group name
4626
            $draft = $contentService->updateContent(
4627
                $draft->getVersionInfo(),
4628
                $contentUpdate
4629
            );
4630
4631
            // Publish updated version
4632
            $contentService->publishVersion($draft->getVersionInfo());
4633
        } catch (Exception $e) {
4634
            // Cleanup hanging transaction on error
4635
            $repository->rollback();
4636
            throw $e;
4637
        }
4638
4639
        // Rollback all changes.
4640
        $repository->rollback();
4641
4642
        // Name will still be "Administrator users"
4643
        $name = $contentService->loadContent($contentId)->getFieldValue('name');
4644
        /* END: Use Case */
4645
4646
        $this->assertEquals('Administrator users', $name);
4647
    }
4648
4649
    /**
4650
     * Test for the updateContent() method.
4651
     *
4652
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
4653
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
4654
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4655
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4656
     */
4657 View Code Duplication
    public function testUpdateContentInTransactionWithCommit()
4658
    {
4659
        $repository = $this->getRepository();
4660
4661
        $contentId = $this->generateId('object', 12);
4662
        /* BEGIN: Use Case */
4663
        // $contentId is the ID of the "Administrator users" user group
4664
4665
        // Load content service
4666
        $contentService = $repository->getContentService();
4667
4668
        // Create a new user group draft
4669
        $draft = $contentService->createContentDraft(
4670
            $contentService->loadContentInfo($contentId)
4671
        );
4672
4673
        // Get an update struct and change the group name
4674
        $contentUpdate = $contentService->newContentUpdateStruct();
4675
        $contentUpdate->setField('name', 'Administrators', 'eng-US');
4676
4677
        // Start a transaction
4678
        $repository->beginTransaction();
4679
4680
        try {
4681
            // Update the group name
4682
            $draft = $contentService->updateContent(
4683
                $draft->getVersionInfo(),
4684
                $contentUpdate
4685
            );
4686
4687
            // Publish updated version
4688
            $contentService->publishVersion($draft->getVersionInfo());
4689
4690
            // Commit all changes.
4691
            $repository->commit();
4692
        } catch (Exception $e) {
4693
            // Cleanup hanging transaction on error
4694
            $repository->rollback();
4695
            throw $e;
4696
        }
4697
4698
        // Name is now "Administrators"
4699
        $name = $contentService->loadContent($contentId)->getFieldValue('name', 'eng-US');
4700
        /* END: Use Case */
4701
4702
        $this->assertEquals('Administrators', $name);
4703
    }
4704
4705
    /**
4706
     * Test for the updateContentMetadata() method.
4707
     *
4708
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4709
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
4710
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4711
     */
4712 View Code Duplication
    public function testUpdateContentMetadataInTransactionWithRollback()
4713
    {
4714
        $repository = $this->getRepository();
4715
4716
        $contentId = $this->generateId('object', 12);
4717
        /* BEGIN: Use Case */
4718
        // $contentId is the ID of the "Administrator users" user group
4719
4720
        // Get the content service
4721
        $contentService = $repository->getContentService();
4722
4723
        // Load a ContentInfo object
4724
        $contentInfo = $contentService->loadContentInfo($contentId);
4725
4726
        // Store remoteId for later testing
4727
        $remoteId = $contentInfo->remoteId;
4728
4729
        // Start a transaction
4730
        $repository->beginTransaction();
4731
4732
        try {
4733
            // Get metadata update struct and change remoteId
4734
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4735
            $metadataUpdate->remoteId = md5(microtime(true));
4736
4737
            // Update the metadata of the published content object
4738
            $contentService->updateContentMetadata(
4739
                $contentInfo,
4740
                $metadataUpdate
4741
            );
4742
        } catch (Exception $e) {
4743
            // Cleanup hanging transaction on error
4744
            $repository->rollback();
4745
            throw $e;
4746
        }
4747
4748
        // Rollback all changes.
4749
        $repository->rollback();
4750
4751
        // Load current remoteId
4752
        $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4753
        /* END: Use Case */
4754
4755
        $this->assertEquals($remoteId, $remoteIdReloaded);
4756
    }
4757
4758
    /**
4759
     * Test for the updateContentMetadata() method.
4760
     *
4761
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4762
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
4763
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4764
     */
4765 View Code Duplication
    public function testUpdateContentMetadataInTransactionWithCommit()
4766
    {
4767
        $repository = $this->getRepository();
4768
4769
        $contentId = $this->generateId('object', 12);
4770
        /* BEGIN: Use Case */
4771
        // $contentId is the ID of the "Administrator users" user group
4772
4773
        // Get the content service
4774
        $contentService = $repository->getContentService();
4775
4776
        // Load a ContentInfo object
4777
        $contentInfo = $contentService->loadContentInfo($contentId);
4778
4779
        // Store remoteId for later testing
4780
        $remoteId = $contentInfo->remoteId;
4781
4782
        // Start a transaction
4783
        $repository->beginTransaction();
4784
4785
        try {
4786
            // Get metadata update struct and change remoteId
4787
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4788
            $metadataUpdate->remoteId = md5(microtime(true));
4789
4790
            // Update the metadata of the published content object
4791
            $contentService->updateContentMetadata(
4792
                $contentInfo,
4793
                $metadataUpdate
4794
            );
4795
4796
            // Commit all changes.
4797
            $repository->commit();
4798
        } catch (Exception $e) {
4799
            // Cleanup hanging transaction on error
4800
            $repository->rollback();
4801
            throw $e;
4802
        }
4803
4804
        // Load current remoteId
4805
        $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4806
        /* END: Use Case */
4807
4808
        $this->assertNotEquals($remoteId, $remoteIdReloaded);
4809
    }
4810
4811
    /**
4812
     * Test for the updateContentMetadata() method, and how cache + transactions play together.
4813
     *
4814
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4815
     * @depends testUpdateContentMetadata
4816
     * @depends testLoadContentInfo
4817
     */
4818 View Code Duplication
    public function testUpdateContentMetadataCheckWithinTransaction()
4819
    {
4820
        $repository = $this->getRepository();
4821
        $contentService = $repository->getContentService();
4822
        $contentId = $this->generateId('object', 12);
4823
4824
        // Load a ContentInfo object, and warmup cache
4825
        $contentInfo = $contentService->loadContentInfo($contentId);
4826
4827
        // Store remoteId for later testing
4828
        $remoteId = $contentInfo->remoteId;
4829
4830
        // Start a transaction
4831
        $repository->beginTransaction();
4832
4833
        try {
4834
            // Get metadata update struct and change remoteId
4835
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4836
            $metadataUpdate->remoteId = md5(microtime(true));
4837
4838
            // Update the metadata of the published content object
4839
            $contentService->updateContentMetadata(
4840
                $contentInfo,
4841
                $metadataUpdate
4842
            );
4843
4844
            // Check that it's been updated
4845
            $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4846
            $this->assertNotEquals($remoteId, $remoteIdReloaded);
4847
4848
            // Commit all changes.
4849
            $repository->commit();
4850
        } catch (Exception $e) {
4851
            // Cleanup hanging transaction on error
4852
            $repository->rollback();
4853
            throw $e;
4854
        }
4855
    }
4856
4857
    /**
4858
     * Test for the deleteVersion() method.
4859
     *
4860
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
4861
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4862
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4863
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
4864
     */
4865 View Code Duplication
    public function testDeleteVersionInTransactionWithRollback()
4866
    {
4867
        $repository = $this->getRepository();
4868
4869
        $contentId = $this->generateId('object', 12);
4870
        /* BEGIN: Use Case */
4871
        // $contentId is the ID of the "Administrator users" user group
4872
4873
        // Get the content service
4874
        $contentService = $repository->getContentService();
4875
4876
        // Start a new transaction
4877
        $repository->beginTransaction();
4878
4879
        try {
4880
            // Create a new draft
4881
            $draft = $contentService->createContentDraft(
4882
                $contentService->loadContentInfo($contentId)
4883
            );
4884
4885
            $contentService->deleteVersion($draft->getVersionInfo());
4886
        } catch (Exception $e) {
4887
            // Cleanup hanging transaction on error
4888
            $repository->rollback();
4889
            throw $e;
4890
        }
4891
4892
        // Rollback all changes.
4893
        $repository->rollback();
4894
4895
        // This array will be empty
4896
        $drafts = $contentService->loadContentDrafts();
4897
        /* END: Use Case */
4898
4899
        $this->assertSame([], $drafts);
4900
    }
4901
4902
    /**
4903
     * Test for the deleteVersion() method.
4904
     *
4905
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
4906
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4907
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4908
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
4909
     */
4910 View Code Duplication
    public function testDeleteVersionInTransactionWithCommit()
4911
    {
4912
        $repository = $this->getRepository();
4913
4914
        $contentId = $this->generateId('object', 12);
4915
        /* BEGIN: Use Case */
4916
        // $contentId is the ID of the "Administrator users" user group
4917
4918
        // Get the content service
4919
        $contentService = $repository->getContentService();
4920
4921
        // Start a new transaction
4922
        $repository->beginTransaction();
4923
4924
        try {
4925
            // Create a new draft
4926
            $draft = $contentService->createContentDraft(
4927
                $contentService->loadContentInfo($contentId)
4928
            );
4929
4930
            $contentService->deleteVersion($draft->getVersionInfo());
4931
4932
            // Commit all changes.
4933
            $repository->commit();
4934
        } catch (Exception $e) {
4935
            // Cleanup hanging transaction on error
4936
            $repository->rollback();
4937
            throw $e;
4938
        }
4939
4940
        // This array will contain no element
4941
        $drafts = $contentService->loadContentDrafts();
4942
        /* END: Use Case */
4943
4944
        $this->assertSame([], $drafts);
4945
    }
4946
4947
    /**
4948
     * Test for the deleteContent() method.
4949
     *
4950
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
4951
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
4952
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4953
     */
4954 View Code Duplication
    public function testDeleteContentInTransactionWithRollback()
4955
    {
4956
        $repository = $this->getRepository();
4957
4958
        $contentId = $this->generateId('object', 11);
4959
        /* BEGIN: Use Case */
4960
        // $contentId is the ID of the "Members" user group in an eZ Publish
4961
        // demo installation
4962
4963
        // Get content service
4964
        $contentService = $repository->getContentService();
4965
4966
        // Load a ContentInfo instance
4967
        $contentInfo = $contentService->loadContentInfo($contentId);
4968
4969
        // Start a new transaction
4970
        $repository->beginTransaction();
4971
4972
        try {
4973
            // Delete content object
4974
            $contentService->deleteContent($contentInfo);
4975
        } catch (Exception $e) {
4976
            // Cleanup hanging transaction on error
4977
            $repository->rollback();
4978
            throw $e;
4979
        }
4980
4981
        // Rollback all changes
4982
        $repository->rollback();
4983
4984
        // This call will return the original content object
4985
        $contentInfo = $contentService->loadContentInfo($contentId);
4986
        /* END: Use Case */
4987
4988
        $this->assertEquals($contentId, $contentInfo->id);
4989
    }
4990
4991
    /**
4992
     * Test for the deleteContent() method.
4993
     *
4994
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
4995
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
4996
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4997
     */
4998 View Code Duplication
    public function testDeleteContentInTransactionWithCommit()
4999
    {
5000
        $repository = $this->getRepository();
5001
5002
        $contentId = $this->generateId('object', 11);
5003
        /* BEGIN: Use Case */
5004
        // $contentId is the ID of the "Members" user group in an eZ Publish
5005
        // demo installation
5006
5007
        // Get content service
5008
        $contentService = $repository->getContentService();
5009
5010
        // Load a ContentInfo instance
5011
        $contentInfo = $contentService->loadContentInfo($contentId);
5012
5013
        // Start a new transaction
5014
        $repository->beginTransaction();
5015
5016
        try {
5017
            // Delete content object
5018
            $contentService->deleteContent($contentInfo);
5019
5020
            // Commit all changes
5021
            $repository->commit();
5022
        } catch (Exception $e) {
5023
            // Cleanup hanging transaction on error
5024
            $repository->rollback();
5025
            throw $e;
5026
        }
5027
5028
        // Deleted content info is not found anymore
5029
        try {
5030
            $contentService->loadContentInfo($contentId);
5031
        } catch (NotFoundException $e) {
5032
            return;
5033
        }
5034
        /* END: Use Case */
5035
5036
        $this->fail('Can still load ContentInfo after commit.');
5037
    }
5038
5039
    /**
5040
     * Test for the copyContent() method.
5041
     *
5042
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
5043
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
5044
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
5045
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
5046
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
5047
     */
5048 View Code Duplication
    public function testCopyContentInTransactionWithRollback()
5049
    {
5050
        $repository = $this->getRepository();
5051
5052
        $contentId = $this->generateId('object', 11);
5053
        $locationId = $this->generateId('location', 13);
5054
        /* BEGIN: Use Case */
5055
        // $contentId is the ID of the "Members" user group in an eZ Publish
5056
        // demo installation
5057
5058
        // $locationId is the ID of the "Administrator users" group location
5059
5060
        // Get services
5061
        $contentService = $repository->getContentService();
5062
        $locationService = $repository->getLocationService();
5063
5064
        // Load content object to copy
5065
        $content = $contentService->loadContent($contentId);
5066
5067
        // Create new target location
5068
        $locationCreate = $locationService->newLocationCreateStruct($locationId);
5069
5070
        // Start a new transaction
5071
        $repository->beginTransaction();
5072
5073
        try {
5074
            // Copy content with all versions and drafts
5075
            $contentService->copyContent(
5076
                $content->contentInfo,
5077
                $locationCreate
5078
            );
5079
        } catch (Exception $e) {
5080
            // Cleanup hanging transaction on error
5081
            $repository->rollback();
5082
            throw $e;
5083
        }
5084
5085
        // Rollback all changes
5086
        $repository->rollback();
5087
5088
        $this->refreshSearch($repository);
5089
5090
        // This array will only contain a single admin user object
5091
        $locations = $locationService->loadLocationChildren(
5092
            $locationService->loadLocation($locationId)
5093
        )->locations;
5094
        /* END: Use Case */
5095
5096
        $this->assertEquals(1, count($locations));
5097
    }
5098
5099
    /**
5100
     * Test for the copyContent() method.
5101
     *
5102
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
5103
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
5104
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
5105
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
5106
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
5107
     */
5108 View Code Duplication
    public function testCopyContentInTransactionWithCommit()
5109
    {
5110
        $repository = $this->getRepository();
5111
5112
        $contentId = $this->generateId('object', 11);
5113
        $locationId = $this->generateId('location', 13);
5114
        /* BEGIN: Use Case */
5115
        // $contentId is the ID of the "Members" user group in an eZ Publish
5116
        // demo installation
5117
5118
        // $locationId is the ID of the "Administrator users" group location
5119
5120
        // Get services
5121
        $contentService = $repository->getContentService();
5122
        $locationService = $repository->getLocationService();
5123
5124
        // Load content object to copy
5125
        $content = $contentService->loadContent($contentId);
5126
5127
        // Create new target location
5128
        $locationCreate = $locationService->newLocationCreateStruct($locationId);
5129
5130
        // Start a new transaction
5131
        $repository->beginTransaction();
5132
5133
        try {
5134
            // Copy content with all versions and drafts
5135
            $contentCopied = $contentService->copyContent(
0 ignored issues
show
Unused Code introduced by
$contentCopied is not used, you could remove the assignment.

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

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

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

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

Loading history...
5136
                $content->contentInfo,
5137
                $locationCreate
5138
            );
5139
5140
            // Commit all changes
5141
            $repository->commit();
5142
        } catch (Exception $e) {
5143
            // Cleanup hanging transaction on error
5144
            $repository->rollback();
5145
            throw $e;
5146
        }
5147
5148
        $this->refreshSearch($repository);
5149
5150
        // This will contain the admin user and the new child location
5151
        $locations = $locationService->loadLocationChildren(
5152
            $locationService->loadLocation($locationId)
5153
        )->locations;
5154
        /* END: Use Case */
5155
5156
        $this->assertEquals(2, count($locations));
5157
    }
5158
5159
    public function testURLAliasesCreatedForNewContent()
5160
    {
5161
        $repository = $this->getRepository();
5162
5163
        $contentService = $repository->getContentService();
5164
        $locationService = $repository->getLocationService();
5165
        $urlAliasService = $repository->getURLAliasService();
5166
5167
        /* BEGIN: Use Case */
5168
        $draft = $this->createContentDraftVersion1();
5169
5170
        // Automatically creates a new URLAlias for the content
5171
        $liveContent = $contentService->publishVersion($draft->getVersionInfo());
5172
        /* END: Use Case */
5173
5174
        $location = $locationService->loadLocation(
5175
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5176
        );
5177
5178
        $aliases = $urlAliasService->listLocationAliases($location, false);
5179
5180
        $this->assertAliasesCorrect(
5181
            [
5182
                '/Design/Plain-site/An-awesome-forum' => [
5183
                    'type' => URLAlias::LOCATION,
5184
                    'destination' => $location->id,
5185
                    'path' => '/Design/Plain-site/An-awesome-forum',
5186
                    'languageCodes' => ['eng-US'],
5187
                    'isHistory' => false,
5188
                    'isCustom' => false,
5189
                    'forward' => false,
5190
                ],
5191
            ],
5192
            $aliases
5193
        );
5194
    }
5195
5196
    public function testURLAliasesCreatedForUpdatedContent()
5197
    {
5198
        $repository = $this->getRepository();
5199
5200
        $contentService = $repository->getContentService();
5201
        $locationService = $repository->getLocationService();
5202
        $urlAliasService = $repository->getURLAliasService();
5203
5204
        /* BEGIN: Use Case */
5205
        $draft = $this->createUpdatedDraftVersion2();
5206
5207
        $location = $locationService->loadLocation(
5208
            $draft->getVersionInfo()->getContentInfo()->mainLocationId
5209
        );
5210
5211
        // Load and assert URL aliases before publishing updated Content, so that
5212
        // SPI cache is warmed up and cache invalidation is also tested.
5213
        $aliases = $urlAliasService->listLocationAliases($location, false);
5214
5215
        $this->assertAliasesCorrect(
5216
            [
5217
                '/Design/Plain-site/An-awesome-forum' => [
5218
                    'type' => URLAlias::LOCATION,
5219
                    'destination' => $location->id,
5220
                    'path' => '/Design/Plain-site/An-awesome-forum',
5221
                    'languageCodes' => ['eng-US'],
5222
                    'alwaysAvailable' => true,
5223
                    'isHistory' => false,
5224
                    'isCustom' => false,
5225
                    'forward' => false,
5226
                ],
5227
            ],
5228
            $aliases
5229
        );
5230
5231
        // Automatically marks old aliases for the content as history
5232
        // and creates new aliases, based on the changes
5233
        $liveContent = $contentService->publishVersion($draft->getVersionInfo());
5234
        /* END: Use Case */
5235
5236
        $location = $locationService->loadLocation(
5237
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5238
        );
5239
5240
        $aliases = $urlAliasService->listLocationAliases($location, false);
5241
5242
        $this->assertAliasesCorrect(
5243
            [
5244
                '/Design/Plain-site/An-awesome-forum2' => [
5245
                    'type' => URLAlias::LOCATION,
5246
                    'destination' => $location->id,
5247
                    'path' => '/Design/Plain-site/An-awesome-forum2',
5248
                    'languageCodes' => ['eng-US'],
5249
                    'alwaysAvailable' => true,
5250
                    'isHistory' => false,
5251
                    'isCustom' => false,
5252
                    'forward' => false,
5253
                ],
5254
                '/Design/Plain-site/An-awesome-forum23' => [
5255
                    'type' => URLAlias::LOCATION,
5256
                    'destination' => $location->id,
5257
                    'path' => '/Design/Plain-site/An-awesome-forum23',
5258
                    'languageCodes' => ['eng-GB'],
5259
                    'alwaysAvailable' => true,
5260
                    'isHistory' => false,
5261
                    'isCustom' => false,
5262
                    'forward' => false,
5263
                ],
5264
            ],
5265
            $aliases
5266
        );
5267
    }
5268
5269
    public function testCustomURLAliasesNotHistorizedOnUpdatedContent()
5270
    {
5271
        $repository = $this->getRepository();
5272
5273
        $contentService = $repository->getContentService();
5274
5275
        /* BEGIN: Use Case */
5276
        $urlAliasService = $repository->getURLAliasService();
5277
        $locationService = $repository->getLocationService();
5278
5279
        $content = $this->createContentVersion1();
5280
5281
        // Create a custom URL alias
5282
        $urlAliasService->createUrlAlias(
5283
            $locationService->loadLocation(
5284
                $content->getVersionInfo()->getContentInfo()->mainLocationId
5285
            ),
5286
            '/my/fancy/story-about-ez-publish',
5287
            'eng-US'
5288
        );
5289
5290
        $draftVersion2 = $contentService->createContentDraft($content->contentInfo);
5291
5292
        $contentUpdate = $contentService->newContentUpdateStruct();
5293
        $contentUpdate->initialLanguageCode = 'eng-US';
5294
        $contentUpdate->setField('name', 'Amazing Bielefeld forum');
5295
5296
        $draftVersion2 = $contentService->updateContent(
5297
            $draftVersion2->getVersionInfo(),
5298
            $contentUpdate
5299
        );
5300
5301
        // Only marks auto-generated aliases as history
5302
        // the custom one is left untouched
5303
        $liveContent = $contentService->publishVersion($draftVersion2->getVersionInfo());
5304
        /* END: Use Case */
5305
5306
        $location = $locationService->loadLocation(
5307
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5308
        );
5309
5310
        $aliases = $urlAliasService->listLocationAliases($location);
5311
5312
        $this->assertAliasesCorrect(
5313
            [
5314
                '/my/fancy/story-about-ez-publish' => [
5315
                    'type' => URLAlias::LOCATION,
5316
                    'destination' => $location->id,
5317
                    'path' => '/my/fancy/story-about-ez-publish',
5318
                    'languageCodes' => ['eng-US'],
5319
                    'isHistory' => false,
5320
                    'isCustom' => true,
5321
                    'forward' => false,
5322
                    'alwaysAvailable' => false,
5323
                ],
5324
            ],
5325
            $aliases
5326
        );
5327
    }
5328
5329
    /**
5330
     * Test to ensure that old versions are not affected by updates to newer
5331
     * drafts.
5332
     */
5333
    public function testUpdatingDraftDoesNotUpdateOldVersions()
5334
    {
5335
        $repository = $this->getRepository();
5336
5337
        $contentService = $repository->getContentService();
5338
5339
        $contentVersion2 = $this->createContentVersion2();
5340
5341
        $loadedContent1 = $contentService->loadContent($contentVersion2->id, null, 1);
5342
        $loadedContent2 = $contentService->loadContent($contentVersion2->id, null, 2);
5343
5344
        $this->assertNotEquals(
5345
            $loadedContent1->getFieldValue('name', 'eng-US'),
5346
            $loadedContent2->getFieldValue('name', 'eng-US')
5347
        );
5348
    }
5349
5350
    /**
5351
     * Test scenario with writer and publisher users.
5352
     * Writer can only create content. Publisher can publish this content.
5353
     */
5354
    public function testPublishWorkflow()
5355
    {
5356
        $repository = $this->getRepository();
5357
        $contentService = $repository->getContentService();
5358
5359
        $this->createRoleWithPolicies('Publisher', [
5360
            ['module' => 'content', 'function' => 'read'],
5361
            ['module' => 'content', 'function' => 'create'],
5362
            ['module' => 'content', 'function' => 'publish'],
5363
        ]);
5364
5365
        $this->createRoleWithPolicies('Writer', [
5366
            ['module' => 'content', 'function' => 'read'],
5367
            ['module' => 'content', 'function' => 'create'],
5368
        ]);
5369
5370
        $writerUser = $this->createCustomUserWithLogin(
5371
            'writer',
5372
            '[email protected]',
5373
            'Writers',
5374
            'Writer'
5375
        );
5376
5377
        $publisherUser = $this->createCustomUserWithLogin(
5378
            'publisher',
5379
            '[email protected]',
5380
            'Publishers',
5381
            'Publisher'
5382
        );
5383
5384
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5385
        $draft = $this->createContentDraftVersion1();
5386
5387
        $repository->getPermissionResolver()->setCurrentUserReference($publisherUser);
5388
        $content = $contentService->publishVersion($draft->versionInfo);
5389
5390
        $contentService->loadContent($content->id);
5391
    }
5392
5393
    /**
5394
     * Test publish / content policy is required to be able to publish content.
5395
     *
5396
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
5397
     * @expectedExceptionMessageRegExp /User does not have access to 'publish' 'content'/
5398
     */
5399
    public function testPublishContentWithoutPublishPolicyThrowsException()
5400
    {
5401
        $repository = $this->getRepository();
5402
5403
        $this->createRoleWithPolicies('Writer', [
5404
            ['module' => 'content', 'function' => 'read'],
5405
            ['module' => 'content', 'function' => 'create'],
5406
            ['module' => 'content', 'function' => 'edit'],
5407
        ]);
5408
        $writerUser = $this->createCustomUserWithLogin(
5409
            'writer',
5410
            '[email protected]',
5411
            'Writers',
5412
            'Writer'
5413
        );
5414
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5415
5416
        $this->createContentVersion1();
5417
    }
5418
5419
    /**
5420
     * Test removal of the specific translation from all the Versions of a Content Object.
5421
     *
5422
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5423
     */
5424 View Code Duplication
    public function testDeleteTranslation()
5425
    {
5426
        $repository = $this->getRepository();
5427
        $contentService = $repository->getContentService();
5428
        $content = $this->createContentVersion2();
5429
5430
        // create multiple versions to exceed archive limit
5431
        for ($i = 0; $i < 5; ++$i) {
5432
            $contentDraft = $contentService->createContentDraft($content->contentInfo);
5433
            $contentUpdateStruct = $contentService->newContentUpdateStruct();
5434
            $contentDraft = $contentService->updateContent(
5435
                $contentDraft->versionInfo,
5436
                $contentUpdateStruct
5437
            );
5438
            $contentService->publishVersion($contentDraft->versionInfo);
5439
        }
5440
5441
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5442
5443
        $this->assertTranslationDoesNotExist('eng-GB', $content->id);
5444
    }
5445
5446
    /**
5447
     * Test deleting a Translation which is initial for some Version, updates initialLanguageCode
5448
     * with mainLanguageCode (assuming they are different).
5449
     */
5450
    public function testDeleteTranslationUpdatesInitialLanguageCodeVersion()
5451
    {
5452
        $repository = $this->getRepository();
5453
        $contentService = $repository->getContentService();
5454
5455
        $content = $this->createContentVersion2();
5456
        // create another, copied, version
5457
        $contentDraft = $contentService->updateContent(
5458
            $contentService->createContentDraft($content->contentInfo)->versionInfo,
5459
            $contentService->newContentUpdateStruct()
5460
        );
5461
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
5462
5463
        // remove first version with only one translation as it is not the subject of this test
5464
        $contentService->deleteVersion(
5465
            $contentService->loadVersionInfo($publishedContent->contentInfo, 1)
5466
        );
5467
5468
        // sanity check
5469
        self::assertEquals('eng-US', $content->contentInfo->mainLanguageCode);
5470
        self::assertEquals('eng-US', $content->versionInfo->initialLanguageCode);
5471
5472
        // update mainLanguageCode so it is different than initialLanguageCode for Version
5473
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5474
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5475
        $content = $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
5476
5477
        $contentService->deleteTranslation($content->contentInfo, 'eng-US');
5478
5479
        $this->assertTranslationDoesNotExist('eng-US', $content->id);
5480
    }
5481
5482
    /**
5483
     * Test removal of the specific translation properly updates languages of the URL alias.
5484
     *
5485
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5486
     */
5487
    public function testDeleteTranslationUpdatesUrlAlias()
5488
    {
5489
        $repository = $this->getRepository();
5490
        $contentService = $repository->getContentService();
5491
        $locationService = $repository->getLocationService();
5492
        $urlAliasService = $repository->getURLAliasService();
5493
5494
        $content = $this->createContentVersion2();
5495
        $mainLocation = $locationService->loadLocation($content->contentInfo->mainLocationId);
5496
5497
        // create custom URL alias for Content main Location
5498
        $urlAliasService->createUrlAlias($mainLocation, '/my-custom-url', 'eng-GB');
5499
5500
        // create secondary Location for Content
5501
        $secondaryLocation = $locationService->createLocation(
5502
            $content->contentInfo,
5503
            $locationService->newLocationCreateStruct(2)
5504
        );
5505
5506
        // create custom URL alias for Content secondary Location
5507
        $urlAliasService->createUrlAlias($secondaryLocation, '/my-secondary-url', 'eng-GB');
5508
5509
        // delete Translation
5510
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5511
5512
        foreach ([$mainLocation, $secondaryLocation] as $location) {
5513
            // check auto-generated URL aliases
5514
            foreach ($urlAliasService->listLocationAliases($location, false) as $alias) {
5515
                self::assertNotContains('eng-GB', $alias->languageCodes);
5516
            }
5517
5518
            // check custom URL aliases
5519
            foreach ($urlAliasService->listLocationAliases($location) as $alias) {
5520
                self::assertNotContains('eng-GB', $alias->languageCodes);
5521
            }
5522
        }
5523
    }
5524
5525
    /**
5526
     * Test removal of a main translation throws BadStateException.
5527
     *
5528
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5529
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5530
     * @expectedExceptionMessage Specified translation is the main translation of the Content Object
5531
     */
5532
    public function testDeleteTranslationMainLanguageThrowsBadStateException()
5533
    {
5534
        $repository = $this->getRepository();
5535
        $contentService = $repository->getContentService();
5536
        $content = $this->createContentVersion2();
5537
5538
        // delete first version which has only one translation
5539
        $contentService->deleteVersion($contentService->loadVersionInfo($content->contentInfo, 1));
5540
5541
        // try to delete main translation
5542
        $contentService->deleteTranslation($content->contentInfo, $content->contentInfo->mainLanguageCode);
5543
    }
5544
5545
    /**
5546
     * Test removal of a Translation is possible when some archived Versions have only this Translation.
5547
     *
5548
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5549
     */
5550
    public function testDeleteTranslationDeletesSingleTranslationVersions()
5551
    {
5552
        $repository = $this->getRepository();
5553
        $contentService = $repository->getContentService();
5554
        // content created by the createContentVersion1 method has eng-US translation only.
5555
        $content = $this->createContentVersion1();
5556
5557
        // create new version and add eng-GB translation
5558
        $contentDraft = $contentService->createContentDraft($content->contentInfo);
5559
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
5560
        $contentUpdateStruct->setField('name', 'Awesome Board', 'eng-GB');
5561
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
5562
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
5563
5564
        // update mainLanguageCode to avoid exception related to that
5565
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5566
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5567
5568
        $content = $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
5569
5570
        $contentService->deleteTranslation($content->contentInfo, 'eng-US');
5571
5572
        $this->assertTranslationDoesNotExist('eng-US', $content->id);
5573
    }
5574
5575
    /**
5576
     * Test removal of the translation by the user who is not allowed to delete a content
5577
     * throws UnauthorizedException.
5578
     *
5579
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5580
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5581
     * @expectedExceptionMessage User does not have access to 'remove' 'content'
5582
     */
5583
    public function testDeleteTranslationThrowsUnauthorizedException()
5584
    {
5585
        $repository = $this->getRepository();
5586
        $contentService = $repository->getContentService();
5587
5588
        $content = $this->createContentVersion2();
5589
5590
        // create user that can read/create/edit but cannot delete content
5591
        $this->createRoleWithPolicies('Writer', [
5592
            ['module' => 'content', 'function' => 'read'],
5593
            ['module' => 'content', 'function' => 'versionread'],
5594
            ['module' => 'content', 'function' => 'create'],
5595
            ['module' => 'content', 'function' => 'edit'],
5596
        ]);
5597
        $writerUser = $this->createCustomUserWithLogin(
5598
            'writer',
5599
            '[email protected]',
5600
            'Writers',
5601
            'Writer'
5602
        );
5603
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5604
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5605
    }
5606
5607
    /**
5608
     * Test removal of a non-existent translation throws InvalidArgumentException.
5609
     *
5610
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5611
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5612
     * @expectedExceptionMessage Argument '$languageCode' is invalid: ger-DE does not exist in the Content item
5613
     */
5614
    public function testDeleteTranslationThrowsInvalidArgumentException()
5615
    {
5616
        $repository = $this->getRepository();
5617
        $contentService = $repository->getContentService();
5618
        // content created by the createContentVersion1 method has eng-US translation only.
5619
        $content = $this->createContentVersion1();
5620
        $contentService->deleteTranslation($content->contentInfo, 'ger-DE');
5621
    }
5622
5623
    /**
5624
     * Test deleting a Translation from Draft.
5625
     *
5626
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5627
     */
5628
    public function testDeleteTranslationFromDraft()
5629
    {
5630
        $repository = $this->getRepository();
5631
        $contentService = $repository->getContentService();
5632
5633
        $languageCode = 'eng-GB';
5634
        $content = $this->createMultipleLanguageContentVersion2();
5635
        $draft = $contentService->createContentDraft($content->contentInfo);
5636
        $draft = $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5637
        $content = $contentService->publishVersion($draft->versionInfo);
5638
5639
        $loadedContent = $contentService->loadContent($content->id);
5640
        self::assertNotContains($languageCode, $loadedContent->versionInfo->languageCodes);
5641
        self::assertEmpty($loadedContent->getFieldsByLanguage($languageCode));
5642
    }
5643
5644
    /**
5645
     * Get values for multilingual field.
5646
     *
5647
     * @return array
5648
     */
5649
    public function providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing()
5650
    {
5651
        return [
5652
            [
5653
                ['eng-US' => 'US Name', 'eng-GB' => 'GB Name'],
5654
            ],
5655
            [
5656
                ['eng-US' => 'Same Name', 'eng-GB' => 'Same Name'],
5657
            ],
5658
        ];
5659
    }
5660
5661
    /**
5662
     * Test deleting a Translation from Draft removes previously stored URL aliases for published Content.
5663
     *
5664
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5665
     *
5666
     * @dataProvider providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing
5667
     *
5668
     * @param string[] $fieldValues translated field values
5669
     *
5670
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
5671
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5672
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
5673
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5674
     */
5675
    public function testDeleteTranslationFromDraftRemovesUrlAliasOnPublishing(array $fieldValues)
5676
    {
5677
        $repository = $this->getRepository();
5678
        $contentService = $repository->getContentService();
5679
        $locationService = $repository->getLocationService();
5680
        $urlAliasService = $repository->getURLAliasService();
5681
5682
        // set language code to be removed
5683
        $languageCode = 'eng-GB';
5684
        $draft = $this->createMultilingualContentDraft(
5685
            'folder',
5686
            2,
5687
            'eng-US',
5688
            [
5689
                'name' => [
5690
                    'eng-GB' => $fieldValues['eng-GB'],
5691
                    'eng-US' => $fieldValues['eng-US'],
5692
                ],
5693
            ]
5694
        );
5695
        $content = $contentService->publishVersion($draft->versionInfo);
5696
5697
        // create secondary location
5698
        $locationService->createLocation(
5699
            $content->contentInfo,
5700
            $locationService->newLocationCreateStruct(5)
5701
        );
5702
5703
        // sanity check
5704
        $locations = $locationService->loadLocations($content->contentInfo);
5705
        self::assertCount(2, $locations, 'Sanity check: Expected to find 2 Locations');
5706
        foreach ($locations as $location) {
5707
            $urlAliasService->createUrlAlias($location, '/us-custom_' . $location->id, 'eng-US');
5708
            $urlAliasService->createUrlAlias($location, '/gb-custom_' . $location->id, 'eng-GB');
5709
5710
            // check default URL aliases
5711
            $aliases = $urlAliasService->listLocationAliases($location, false, $languageCode);
5712
            self::assertNotEmpty($aliases, 'Sanity check: URL alias for the translation does not exist');
5713
5714
            // check custom URL aliases
5715
            $aliases = $urlAliasService->listLocationAliases($location, true, $languageCode);
5716
            self::assertNotEmpty($aliases, 'Sanity check: Custom URL alias for the translation does not exist');
5717
        }
5718
5719
        // delete translation and publish new version
5720
        $draft = $contentService->createContentDraft($content->contentInfo);
5721
        $draft = $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5722
        $contentService->publishVersion($draft->versionInfo);
5723
5724
        // check that aliases does not exist
5725
        foreach ($locations as $location) {
5726
            // check default URL aliases
5727
            $aliases = $urlAliasService->listLocationAliases($location, false, $languageCode);
5728
            self::assertEmpty($aliases, 'URL alias for the deleted translation still exists');
5729
5730
            // check custom URL aliases
5731
            $aliases = $urlAliasService->listLocationAliases($location, true, $languageCode);
5732
            self::assertEmpty($aliases, 'Custom URL alias for the deleted translation still exists');
5733
        }
5734
    }
5735
5736
    /**
5737
     * Test that URL aliases for deleted Translations are properly archived.
5738
     */
5739
    public function testDeleteTranslationFromDraftArchivesUrlAliasOnPublishing()
5740
    {
5741
        $repository = $this->getRepository();
5742
        $contentService = $repository->getContentService();
5743
        $urlAliasService = $repository->getURLAliasService();
5744
5745
        $content = $contentService->publishVersion(
5746
            $this->createMultilingualContentDraft(
5747
                'folder',
5748
                2,
5749
                'eng-US',
5750
                [
5751
                    'name' => [
5752
                        'eng-GB' => 'BritishEnglishContent',
5753
                        'eng-US' => 'AmericanEnglishContent',
5754
                    ],
5755
                ]
5756
            )->versionInfo
5757
        );
5758
5759
        $unrelatedContent = $contentService->publishVersion(
5760
            $this->createMultilingualContentDraft(
5761
                'folder',
5762
                2,
5763
                'eng-US',
5764
                [
5765
                    'name' => [
5766
                        'eng-GB' => 'AnotherBritishContent',
5767
                        'eng-US' => 'AnotherAmericanContent',
5768
                    ],
5769
                ]
5770
            )->versionInfo
5771
        );
5772
5773
        $urlAlias = $urlAliasService->lookup('/BritishEnglishContent');
5774
        self::assertFalse($urlAlias->isHistory);
5775
        self::assertEquals($urlAlias->path, '/BritishEnglishContent');
5776
        self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId);
5777
5778
        $draft = $contentService->deleteTranslationFromDraft(
5779
            $contentService->createContentDraft($content->contentInfo)->versionInfo,
5780
            'eng-GB'
5781
        );
5782
        $content = $contentService->publishVersion($draft->versionInfo);
5783
5784
        $urlAlias = $urlAliasService->lookup('/BritishEnglishContent');
5785
        self::assertTrue($urlAlias->isHistory);
5786
        self::assertEquals($urlAlias->path, '/BritishEnglishContent');
5787
        self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId);
5788
5789
        $unrelatedUrlAlias = $urlAliasService->lookup('/AnotherBritishContent');
5790
        self::assertFalse($unrelatedUrlAlias->isHistory);
5791
        self::assertEquals($unrelatedUrlAlias->path, '/AnotherBritishContent');
5792
        self::assertEquals($unrelatedUrlAlias->destination, $unrelatedContent->contentInfo->mainLocationId);
5793
    }
5794
5795
    /**
5796
     * Test deleting a Translation from Draft which has single Translation throws BadStateException.
5797
     *
5798
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5799
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5800
     * @expectedExceptionMessage Specified Translation is the only one Content Object Version has
5801
     */
5802
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnSingleTranslation()
5803
    {
5804
        $repository = $this->getRepository();
5805
        $contentService = $repository->getContentService();
5806
5807
        // create Content with single Translation
5808
        $publishedContent = $contentService->publishVersion(
5809
            $this->createContentDraft(
5810
                'forum',
5811
                2,
5812
                ['name' => 'Eng-US Version name']
5813
            )->versionInfo
5814
        );
5815
5816
        // update mainLanguageCode to avoid exception related to trying to delete main Translation
5817
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5818
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5819
        $publishedContent = $contentService->updateContentMetadata(
5820
            $publishedContent->contentInfo,
5821
            $contentMetadataUpdateStruct
5822
        );
5823
5824
        // create single Translation Version from the first one
5825
        $draft = $contentService->createContentDraft(
5826
            $publishedContent->contentInfo,
5827
            $publishedContent->versionInfo
5828
        );
5829
5830
        // attempt to delete Translation
5831
        $contentService->deleteTranslationFromDraft($draft->versionInfo, 'eng-US');
5832
    }
5833
5834
    /**
5835
     * Test deleting the Main Translation from Draft throws BadStateException.
5836
     *
5837
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5838
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5839
     * @expectedExceptionMessage Specified Translation is the main Translation of the Content Object
5840
     */
5841
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnMainTranslation()
5842
    {
5843
        $repository = $this->getRepository();
5844
        $contentService = $repository->getContentService();
5845
5846
        $mainLanguageCode = 'eng-US';
5847
        $draft = $this->createMultilingualContentDraft(
5848
            'forum',
5849
            2,
5850
            $mainLanguageCode,
5851
            [
5852
                'name' => [
5853
                    'eng-US' => 'An awesome eng-US forum',
5854
                    'eng-GB' => 'An awesome eng-GB forum',
5855
                ],
5856
            ]
5857
        );
5858
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $mainLanguageCode);
5859
    }
5860
5861
    /**
5862
     * Test deleting the Translation from Published Version throws BadStateException.
5863
     *
5864
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5865
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5866
     * @expectedExceptionMessage Version is not a draft
5867
     */
5868 View Code Duplication
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnPublishedVersion()
5869
    {
5870
        $repository = $this->getRepository();
5871
        $contentService = $repository->getContentService();
5872
5873
        $languageCode = 'eng-US';
5874
        $content = $this->createMultipleLanguageContentVersion2();
5875
        $draft = $contentService->createContentDraft($content->contentInfo);
5876
        $publishedContent = $contentService->publishVersion($draft->versionInfo);
5877
        $contentService->deleteTranslationFromDraft($publishedContent->versionInfo, $languageCode);
5878
    }
5879
5880
    /**
5881
     * Test deleting a Translation from Draft throws UnauthorizedException if user cannot edit Content.
5882
     *
5883
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5884
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5885
     * @expectedExceptionMessage User does not have access to 'edit' 'content'
5886
     */
5887
    public function testDeleteTranslationFromDraftThrowsUnauthorizedException()
5888
    {
5889
        $repository = $this->getRepository();
5890
        $contentService = $repository->getContentService();
5891
5892
        $languageCode = 'eng-GB';
5893
        $content = $this->createMultipleLanguageContentVersion2();
5894
        $draft = $contentService->createContentDraft($content->contentInfo);
5895
5896
        // create user that can read/create/delete but cannot edit or content
5897
        $this->createRoleWithPolicies('Writer', [
5898
            ['module' => 'content', 'function' => 'read'],
5899
            ['module' => 'content', 'function' => 'versionread'],
5900
            ['module' => 'content', 'function' => 'create'],
5901
            ['module' => 'content', 'function' => 'delete'],
5902
        ]);
5903
        $writerUser = $this->createCustomUserWithLogin(
5904
            'user',
5905
            '[email protected]',
5906
            'Writers',
5907
            'Writer'
5908
        );
5909
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5910
5911
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5912
    }
5913
5914
    /**
5915
     * Test deleting a non-existent Translation from Draft throws InvalidArgumentException.
5916
     *
5917
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5918
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5919
     * @expectedExceptionMessageRegExp /The Version \(ContentId=\d+, VersionNo=\d+\) is not translated into ger-DE/
5920
     */
5921
    public function testDeleteTranslationFromDraftThrowsInvalidArgumentException()
5922
    {
5923
        $repository = $this->getRepository();
5924
        $contentService = $repository->getContentService();
5925
5926
        $languageCode = 'ger-DE';
5927
        $content = $this->createMultipleLanguageContentVersion2();
5928
        $draft = $contentService->createContentDraft($content->contentInfo);
5929
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5930
    }
5931
5932
    /**
5933
     * Test for the newTranslationInfo() method.
5934
     *
5935
     * @covers \eZ\Publish\Core\Repository\ContentService::newTranslationInfo
5936
     */
5937
    public function testNewTranslationInfo()
5938
    {
5939
        $repository = $this->getRepository();
5940
        $contentService = $repository->getContentService();
5941
5942
        $translationInfo = $contentService->newTranslationInfo();
5943
5944
        $this->assertInstanceOf(
5945
            TranslationInfo::class,
5946
            $translationInfo
5947
        );
5948
5949
        foreach ($translationInfo as $propertyName => $propertyValue) {
0 ignored issues
show
Bug introduced by
The expression $translationInfo of type object<eZ\Publish\API\Re...ontent\TranslationInfo> is not traversable.
Loading history...
5950
            $this->assertNull($propertyValue, "Property '{$propertyName}' initial value should be null'");
5951
        }
5952
    }
5953
5954
    /**
5955
     * Test loading list of Content items.
5956
     */
5957
    public function testLoadContentListByContentInfo()
5958
    {
5959
        $repository = $this->getRepository();
5960
        $contentService = $repository->getContentService();
5961
        $locationService = $repository->getLocationService();
5962
5963
        $allLocationsCount = $locationService->getAllLocationsCount();
5964
        $contentInfoList = array_map(
5965
            function (Location $location) {
5966
                return $location->contentInfo;
5967
            },
5968
            $locationService->loadAllLocations(0, $allLocationsCount)
5969
        );
5970
5971
        $contentList = $contentService->loadContentListByContentInfo($contentInfoList);
5972
        self::assertCount(count($contentInfoList), $contentList);
5973
        foreach ($contentList as $content) {
5974
            try {
5975
                $loadedContent = $contentService->loadContent($content->id);
5976
                self::assertEquals($loadedContent, $content, "Failed to properly bulk-load Content {$content->id}");
5977
            } catch (NotFoundException $e) {
5978
                self::fail("Failed to load Content {$content->id}: {$e->getMessage()}");
5979
            } catch (UnauthorizedException $e) {
5980
                self::fail("Failed to load Content {$content->id}: {$e->getMessage()}");
5981
            }
5982
        }
5983
    }
5984
5985
    /**
5986
     * Asserts that all aliases defined in $expectedAliasProperties with the
5987
     * given properties are available in $actualAliases and not more.
5988
     *
5989
     * @param array $expectedAliasProperties
5990
     * @param array $actualAliases
5991
     */
5992
    private function assertAliasesCorrect(array $expectedAliasProperties, array $actualAliases)
5993
    {
5994
        foreach ($actualAliases as $actualAlias) {
5995
            if (!isset($expectedAliasProperties[$actualAlias->path])) {
5996
                $this->fail(
5997
                    sprintf(
5998
                        'Alias with path "%s" in languages "%s" not expected.',
5999
                        $actualAlias->path,
6000
                        implode(', ', $actualAlias->languageCodes)
6001
                    )
6002
                );
6003
            }
6004
6005
            foreach ($expectedAliasProperties[$actualAlias->path] as $propertyName => $propertyValue) {
6006
                $this->assertEquals(
6007
                    $propertyValue,
6008
                    $actualAlias->$propertyName,
6009
                    sprintf(
6010
                        'Property $%s incorrect on alias with path "%s" in languages "%s".',
6011
                        $propertyName,
6012
                        $actualAlias->path,
6013
                        implode(', ', $actualAlias->languageCodes)
6014
                    )
6015
                );
6016
            }
6017
6018
            unset($expectedAliasProperties[$actualAlias->path]);
6019
        }
6020
6021
        if (!empty($expectedAliasProperties)) {
6022
            $this->fail(
6023
                sprintf(
6024
                    'Missing expected aliases with paths "%s".',
6025
                    implode('", "', array_keys($expectedAliasProperties))
6026
                )
6027
            );
6028
        }
6029
    }
6030
6031
    /**
6032
     * Asserts that the given fields are equal to the default fields fixture.
6033
     *
6034
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6035
     */
6036
    private function assertAllFieldsEquals(array $fields)
6037
    {
6038
        $actual = $this->normalizeFields($fields);
6039
        $expected = $this->normalizeFields($this->createFieldsFixture());
6040
6041
        $this->assertEquals($expected, $actual);
6042
    }
6043
6044
    /**
6045
     * Asserts that the given fields are equal to a language filtered set of the
6046
     * default fields fixture.
6047
     *
6048
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6049
     * @param string $languageCode
6050
     */
6051
    private function assertLocaleFieldsEquals(array $fields, $languageCode)
6052
    {
6053
        $actual = $this->normalizeFields($fields);
6054
6055
        $expected = [];
6056
        foreach ($this->normalizeFields($this->createFieldsFixture()) as $field) {
6057
            if ($field->languageCode !== $languageCode) {
6058
                continue;
6059
            }
6060
            $expected[] = $field;
6061
        }
6062
6063
        $this->assertEquals($expected, $actual);
6064
    }
6065
6066
    /**
6067
     * This method normalizes a set of fields and returns a normalized set.
6068
     *
6069
     * Normalization means it resets the storage specific field id to zero and
6070
     * it sorts the field by their identifier and their language code. In
6071
     * addition, the field value is removed, since this one depends on the
6072
     * specific FieldType, which is tested in a dedicated integration test.
6073
     *
6074
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6075
     *
6076
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6077
     */
6078
    private function normalizeFields(array $fields)
6079
    {
6080
        $normalized = [];
6081 View Code Duplication
        foreach ($fields as $field) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
6082
            $normalized[] = new Field(
6083
                [
6084
                    'id' => 0,
6085
                    'value' => ($field->value !== null ? true : null),
6086
                    'languageCode' => $field->languageCode,
6087
                    'fieldDefIdentifier' => $field->fieldDefIdentifier,
6088
                    'fieldTypeIdentifier' => $field->fieldTypeIdentifier,
6089
                ]
6090
            );
6091
        }
6092
        usort(
6093
            $normalized,
6094 View Code Duplication
            function ($field1, $field2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
6095
                if (0 === ($return = strcasecmp($field1->fieldDefIdentifier, $field2->fieldDefIdentifier))) {
6096
                    return strcasecmp($field1->languageCode, $field2->languageCode);
6097
                }
6098
6099
                return $return;
6100
            }
6101
        );
6102
6103
        return $normalized;
6104
    }
6105
6106
    /**
6107
     * Returns a filtered set of the default fields fixture.
6108
     *
6109
     * @param string $languageCode
6110
     *
6111
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6112
     */
6113
    private function createLocaleFieldsFixture($languageCode)
6114
    {
6115
        $fields = [];
6116
        foreach ($this->createFieldsFixture() as $field) {
6117
            if (null === $field->languageCode || $languageCode === $field->languageCode) {
6118
                $fields[] = $field;
6119
            }
6120
        }
6121
6122
        return $fields;
6123
    }
6124
6125
    /**
6126
     * Asserts that given Content has default ContentStates.
6127
     *
6128
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
6129
     */
6130 View Code Duplication
    private function assertDefaultContentStates(ContentInfo $contentInfo)
6131
    {
6132
        $repository = $this->getRepository();
6133
        $objectStateService = $repository->getObjectStateService();
6134
6135
        $objectStateGroups = $objectStateService->loadObjectStateGroups();
6136
6137
        foreach ($objectStateGroups as $objectStateGroup) {
6138
            $contentState = $objectStateService->getContentState($contentInfo, $objectStateGroup);
6139
            foreach ($objectStateService->loadObjectStates($objectStateGroup) as $objectState) {
6140
                // Only check the first object state which is the default one.
6141
                $this->assertEquals(
6142
                    $objectState,
6143
                    $contentState
6144
                );
6145
                break;
6146
            }
6147
        }
6148
    }
6149
6150
    /**
6151
     * Assert that given Content has no references to a translation specified by the $languageCode.
6152
     *
6153
     * @param string $languageCode
6154
     * @param int $contentId
6155
     */
6156
    private function assertTranslationDoesNotExist($languageCode, $contentId)
6157
    {
6158
        $repository = $this->getRepository();
6159
        $contentService = $repository->getContentService();
6160
6161
        $content = $contentService->loadContent($contentId);
6162
6163
        foreach ($content->fields as $fieldIdentifier => $field) {
6164
            /** @var array $field */
6165
            self::assertArrayNotHasKey($languageCode, $field);
6166
            self::assertNotEquals($languageCode, $content->contentInfo->mainLanguageCode);
6167
            self::assertArrayNotHasKey($languageCode, $content->versionInfo->getNames());
6168
            self::assertNotEquals($languageCode, $content->versionInfo->initialLanguageCode);
6169
            self::assertNotContains($languageCode, $content->versionInfo->languageCodes);
6170
        }
6171
        foreach ($contentService->loadVersions($content->contentInfo) as $versionInfo) {
6172
            self::assertArrayNotHasKey($languageCode, $versionInfo->getNames());
6173
            self::assertNotEquals($languageCode, $versionInfo->contentInfo->mainLanguageCode);
6174
            self::assertNotEquals($languageCode, $versionInfo->initialLanguageCode);
6175
            self::assertNotContains($languageCode, $versionInfo->languageCodes);
6176
        }
6177
    }
6178
6179
    /**
6180
     * Returns the default fixture of fields used in most tests.
6181
     *
6182
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6183
     */
6184
    private function createFieldsFixture()
6185
    {
6186
        return [
6187
            new Field(
6188
                [
6189
                    'id' => 0,
6190
                    'value' => 'Foo',
6191
                    'languageCode' => 'eng-US',
6192
                    'fieldDefIdentifier' => 'description',
6193
                    'fieldTypeIdentifier' => 'ezrichtext',
6194
                ]
6195
            ),
6196
            new Field(
6197
                [
6198
                    'id' => 0,
6199
                    'value' => 'Bar',
6200
                    'languageCode' => 'eng-GB',
6201
                    'fieldDefIdentifier' => 'description',
6202
                    'fieldTypeIdentifier' => 'ezrichtext',
6203
                ]
6204
            ),
6205
            new Field(
6206
                [
6207
                    'id' => 0,
6208
                    'value' => 'An awesome multi-lang forum²',
6209
                    'languageCode' => 'eng-US',
6210
                    'fieldDefIdentifier' => 'name',
6211
                    'fieldTypeIdentifier' => 'ezstring',
6212
                ]
6213
            ),
6214
            new Field(
6215
                [
6216
                    'id' => 0,
6217
                    'value' => 'An awesome multi-lang forum²³',
6218
                    'languageCode' => 'eng-GB',
6219
                    'fieldDefIdentifier' => 'name',
6220
                    'fieldTypeIdentifier' => 'ezstring',
6221
                ]
6222
            ),
6223
        ];
6224
    }
6225
6226
    /**
6227
     * Gets expected property values for the "Media" ContentInfo ValueObject.
6228
     *
6229
     * @return array
6230
     */
6231 View Code Duplication
    private function getExpectedMediaContentInfoProperties()
6232
    {
6233
        return [
6234
            'id' => 41,
6235
            'contentTypeId' => 1,
6236
            'name' => 'Media',
6237
            'sectionId' => 3,
6238
            'currentVersionNo' => 1,
6239
            'published' => true,
6240
            'ownerId' => 14,
6241
            'modificationDate' => $this->createDateTime(1060695457),
6242
            'publishedDate' => $this->createDateTime(1060695457),
6243
            'alwaysAvailable' => 1,
6244
            'remoteId' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
6245
            'mainLanguageCode' => 'eng-US',
6246
            'mainLocationId' => 43,
6247
            'status' => ContentInfo::STATUS_PUBLISHED,
6248
        ];
6249
    }
6250
}
6251