Completed
Push — refactor-content-service-integ... ( 5a024e )
by
unknown
18:50
created

ContentServiceTest   F

Complexity

Total Complexity 258

Size/Duplication

Total Lines 6717
Duplicated Lines 24.58 %

Coupling/Cohesion

Components 1
Dependencies 34

Importance

Changes 0
Metric Value
dl 1651
loc 6717
rs 0.8
c 0
b 0
f 0
wmc 258
lcom 1
cbo 34

186 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 9 1
A testNewContentCreateStruct() 0 17 1
A testCreateContent() 0 28 2
A testCreateContentAndPublishWithPrivilegedAnonymousUser() 0 50 2
A testCreateContentSetsContentInfo() 0 6 1
A testCreateContentSetsExpectedContentInfo() 0 30 1
A testCreateContentSetsVersionInfo() 0 6 1
A testCreateContentSetsExpectedVersionInfo() 0 20 1
A testCreateContentSetsExpectedContentType() 0 20 1
A testCreateContentThrowsInvalidArgumentException() 0 34 2
A testCreateContentThrowsInvalidArgumentExceptionOnFieldTypeNotAccept() 19 19 1
A testCreateContentThrowsContentFieldValidationException() 0 20 1
A testCreateContentRequiredFieldMissing() 18 18 1
A testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately() 0 16 1
A testCreateContentThrowsInvalidArgumentExceptionWithLocationCreateParameter() 0 54 1
A testLoadContentInfo() 19 19 1
A testLoadContentInfoSetsExpectedContentInfo() 0 7 1
A testLoadContentInfoThrowsNotFoundException() 12 12 1
A testLoadContentInfoList() 0 15 1
A testLoadContentInfoListSkipsNotFoundItems() 10 10 1
A testLoadContentInfoByRemoteId() 0 15 1
A testLoadContentInfoByRemoteIdSetsExpectedContentInfo() 21 21 1
A testLoadContentInfoByRemoteIdThrowsNotFoundException() 0 11 1
A testLoadVersionInfo() 22 22 1
A testLoadVersionInfoById() 21 21 1
A testLoadVersionInfoByIdSetsExpectedVersionInfo() 0 25 1
A testLoadVersionInfoByIdThrowsNotFoundException() 12 12 1
A testLoadContentByContentInfo() 22 22 1
A testLoadContentByVersionInfo() 25 25 1
A testLoadContent() 19 19 1
A testLoadContentThrowsNotFoundException() 12 12 1
A contentRemoteIdVersionLanguageProvider() 0 13 1
A testLoadContentByRemoteId() 0 19 3
A testLoadContentByRemoteIdThrowsNotFoundException() 0 12 1
A testPublishVersion() 0 18 1
A testPublishVersionSetsExpectedContentInfo() 0 30 1
A testPublishVersionSetsExpectedVersionInfo() 0 28 1
A testPublishVersionSetsExpectedContentType() 0 20 1
A testPublishVersionCreatesLocationsDefinedOnCreate() 0 20 1
A testCreateContentWithLocationCreateParameterCreatesExpectedLocation() 0 26 1
A testPublishVersionThrowsBadStateException() 17 17 1
A testPublishVersionDoesNotChangePublishedDate() 0 26 1
A testCreateContentDraft() 0 20 1
A testCreateContentDraftAndLoadAccess() 21 21 1
A testCreateContentDraftSetsExpectedProperties() 0 13 1
A testCreateContentDraftSetsContentInfo() 0 25 1
A testCreateContentDraftSetsVersionInfo() 0 24 1
A testCreateContentDraftLoadVersionInfoStillLoadsPublishedVersion() 18 18 1
A testCreateContentDraftLoadContentStillLoadsPublishedVersion() 18 18 1
A testCreateContentDraftLoadContentByRemoteIdStillLoadsPublishedVersion() 18 18 1
A testCreateContentDraftLoadContentByContentInfoStillLoadsPublishedVersion() 18 18 1
A testNewContentUpdateStruct() 0 23 1
A testUpdateContent() 0 19 1
A testUpdateContentWithDifferentUser() 0 19 1
A testUpdateContentSetsExpectedFields() 0 45 1
A testUpdateContentThrowsBadStateException() 24 24 1
A testUpdateContentThrowsInvalidArgumentExceptionWhenFieldTypeDoesNotAccept() 22 22 1
A testUpdateContentWhenMandatoryFieldIsEmpty() 24 24 1
A testUpdateContentThrowsContentFieldValidationException() 0 24 1
A testUpdateContentValidatorIgnoresRequiredFieldsOfNotUpdatedLanguages() 0 47 1
A testUpdateContentWithNotUpdatingMandatoryField() 0 38 5
A testCreateContentDraftWithSecondParameter() 18 18 1
A testCreateContentDraftWithThirdParameter() 20 20 1
A testPublishVersionFromContentDraft() 26 26 1
A testPublishVersionFromContentDraftArchivesOldVersion() 26 26 1
A testPublishVersionFromContentDraftUpdatesContentInfoCurrentVersion() 0 8 1
A testPublishVersionFromOldContentDraftArchivesNewerVersionNo() 25 25 1
B testPublishVersionNotCreatingUnlimitedArchives() 0 62 1
A testNewContentMetadataUpdateStruct() 0 24 2
A testUpdateContentMetadata() 0 32 1
A testUpdateContentMetadataSetsExpectedProperties() 0 29 1
A testUpdateContentMetadataNotUpdatesContentVersion() 0 4 1
A testUpdateContentMetadataThrowsInvalidArgumentExceptionOnDuplicateRemoteId() 0 24 1
A testUpdateContentMetadataThrowsInvalidArgumentExceptionOnNoMetadataPropertiesSet() 0 12 1
A testDeleteContent() 21 21 2
A testDeleteContentWithEmptyBinaryField() 21 21 2
A testLoadContentDraftsReturnsEmptyArrayByDefault() 0 8 1
A testLoadContentDrafts() 0 40 1
A testLoadContentDraftsWithFirstParameter() 0 44 1
A testLoadVersionInfoWithSecondParameter() 0 23 1
A testLoadVersionInfoThrowsNotFoundExceptionWithSecondParameter() 0 14 1
A testLoadVersionInfoByIdWithSecondParameter() 0 28 1
A testLoadVersionInfoByIdWithSecondParameterSetsExpectedVersionInfo() 0 41 1
A testLoadVersionInfoByIdThrowsNotFoundExceptionWithSecondParameter() 14 14 1
B testLoadContentByVersionInfoWithSecondParameter() 7 82 4
B testLoadContentByContentInfoWithLanguageParameters() 0 135 1
A testLoadContentByContentInfoWithVersionNumberParameter() 30 30 1
A testLoadContentByContentInfoThrowsNotFoundExceptionWithVersionNumberParameter() 14 14 1
A testLoadContentWithSecondParameter() 17 17 1
A testLoadContentWithSecondParameterThrowsNotFoundException() 0 8 1
A testLoadContentWithThirdParameter() 23 23 1
A testLoadContentThrowsNotFoundExceptionWithThirdParameter() 14 14 1
A testLoadContentByRemoteIdWithSecondParameter() 22 22 1
A testLoadContentByRemoteIdWithThirdParameter() 27 27 1
A testLoadContentByRemoteIdThrowsNotFoundExceptionWithThirdParameter() 0 18 1
A testLoadContentWithPrioritizedLanguagesList() 0 20 2
A getPrioritizedLanguageList() 0 9 1
A testDeleteVersion() 0 26 1
A testDeleteVersionThrowsBadStateExceptionOnPublishedVersion() 0 14 1
A testDeleteVersionWorksIfOnlyVersionIsDraft() 0 16 1
A testLoadVersions() 0 22 1
A testLoadVersionsSetsExpectedVersionInfo() 0 43 1
B testCopyContent() 59 59 1
A testCopyContentWithNewOwner() 0 45 1
B testCopyContentWithGivenVersion() 56 56 1
A testAddRelation() 0 28 1
A testAddRelationAddsRelationToContent() 0 7 1
A assertExpectedRelations() 0 17 1
A testAddRelationSetsExpectedRelations() 0 4 1
A testCreateContentDraftWithRelations() 22 22 1
A testCreateContentDraftWithRelationsCreatesRelations() 0 9 1
A testCreateContentDraftWithRelationsCreatesExpectedRelations() 0 4 1
A testAddRelationThrowsBadStateException() 22 22 1
B testLoadRelations() 0 67 1
B testLoadRelationsSkipsArchivedContent() 0 58 1
A testLoadRelationsSkipsDraftContent() 0 54 1
B testLoadReverseRelations() 0 86 1
B testLoadReverseRelationsSkipsArchivedContent() 0 76 1
B testLoadReverseRelationsSkipsDraftContent() 0 68 1
A testDeleteRelation() 0 30 1
A testDeleteRelationThrowsBadStateException() 34 34 1
A testDeleteRelationThrowsInvalidArgumentException() 23 23 1
A testCreateContentInTransactionWithRollback() 0 47 4
A testCreateContentInTransactionWithCommit() 0 42 3
A testCreateContentWithLocationCreateParameterInTransactionWithRollback() 33 33 3
A testCreateContentWithLocationCreateParameterInTransactionWithCommit() 29 29 2
A testCreateContentDraftInTransactionWithRollback() 0 42 3
A testCreateContentDraftInTransactionWithCommit() 40 40 2
A testPublishVersionInTransactionWithRollback() 44 44 3
A testPublishVersionInTransactionWithCommit() 40 40 2
A testUpdateContentInTransactionWithRollback() 47 47 2
A testUpdateContentInTransactionWithCommit() 47 47 2
A testUpdateContentMetadataInTransactionWithRollback() 45 45 2
A testUpdateContentMetadataInTransactionWithCommit() 45 45 2
A testDeleteVersionInTransactionWithRollback() 36 36 2
A testDeleteVersionInTransactionWithCommit() 36 36 2
A testDeleteContentInTransactionWithRollback() 36 36 2
A testDeleteContentInTransactionWithCommit() 40 40 3
A testCopyContentInTransactionWithRollback() 50 50 2
A testCopyContentInTransactionWithCommit() 50 50 2
A testURLAliasesCreatedForNewContent() 0 36 1
B testURLAliasesCreatedForUpdatedContent() 0 72 1
B testCustomURLAliasesNotHistorizedOnUpdatedContent() 0 59 1
A testUpdatingDraftDoesNotUpdateOldVersions() 0 16 1
A testPublishWorkflow() 0 38 1
A testPublishContentWithoutPublishPolicyThrowsException() 0 19 1
A testDeleteTranslation() 21 21 2
A testDeleteTranslationUpdatesInitialLanguageCodeVersion() 0 31 1
A testDeleteTranslationUpdatesUrlAlias() 0 37 4
A testDeleteTranslationMainLanguageThrowsBadStateException() 0 12 1
A testDeleteTranslationDeletesSingleTranslationVersions() 0 24 1
A testDeleteTranslationThrowsUnauthorizedException() 0 23 1
A testDeleteTranslationThrowsInvalidArgumentException() 0 8 1
A testDeleteTranslationFromDraft() 0 15 1
A providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing() 0 11 1
B testDeleteTranslationFromDraftRemovesUrlAliasOnPublishing() 0 60 3
B testDeleteTranslationFromDraftArchivesUrlAliasOnPublishing() 0 55 1
A testDeleteTranslationFromDraftThrowsBadStateExceptionOnSingleTranslation() 0 31 1
A testDeleteTranslationFromDraftThrowsBadStateExceptionOnMainTranslation() 0 19 1
A testDeleteTranslationFromDraftThrowsBadStateExceptionOnPublishedVersion() 11 11 1
A testDeleteTranslationFromDraftThrowsUnauthorizedException() 0 26 1
A testDeleteTranslationFromDraftThrowsInvalidArgumentException() 0 10 1
A testLoadContentListByContentInfo() 0 27 4
A testLoadVersionsAfterDeletingTwoDrafts() 0 30 3
A testLoadVersionsOfStatusDraft() 0 16 1
A testLoadVersionsOfStatusArchived() 0 18 1
A assertAliasesCorrect() 0 38 5
A assertAllFieldsEquals() 0 7 1
A assertLocaleFieldsEquals() 0 14 3
A normalizeFields() 7 27 4
A createLocaleFieldsFixture() 0 11 4
A assertDefaultContentStates() 0 19 3
A assertTranslationDoesNotExist() 0 22 3
A createFieldsFixture() 0 41 1
A getExpectedMediaContentInfoProperties() 19 19 1
A testHideContent() 0 39 1
A testRevealContent() 0 52 1
B testRevealContentWithHiddenParent() 11 58 3
B testRevealContentWithHiddenChildren() 11 68 3
A testHideContentWithParentLocation() 0 52 1
A testChangeContentName() 0 24 1
B testCopyTranslationsFromPublishedToDraft() 0 66 1
A createParentLocationsForHideReveal() 0 10 1
A filterHiddenLocations() 0 11 1
A testPublishVersionWithSelectedLanguages() 0 33 1
A testCreateContentWithRomanianSpecialCharsInTitle() 0 13 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ContentServiceTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ContentServiceTest, and based on these observations, apply Extract Interface, too.

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\LocationService;
12
use eZ\Publish\API\Repository\Values\Content\Content;
13
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
14
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
15
use eZ\Publish\API\Repository\Values\Content\ContentMetadataUpdateStruct;
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\URLAlias;
19
use eZ\Publish\API\Repository\Values\Content\Relation;
20
use eZ\Publish\API\Repository\Values\Content\VersionInfo;
21
use eZ\Publish\API\Repository\Values\User\Limitation\SectionLimitation;
22
use eZ\Publish\API\Repository\Values\User\Limitation\LocationLimitation;
23
use eZ\Publish\API\Repository\Values\User\Limitation\ContentTypeLimitation;
24
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
25
use DOMDocument;
26
use Exception;
27
use eZ\Publish\Core\Repository\Values\Content\ContentUpdateStruct;
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
    /** @var \eZ\Publish\API\Repository\PermissionResolver */
38
    private $permissionResolver;
39
40
    /** @var \eZ\Publish\API\Repository\ContentService */
41
    private $contentService;
42
43
    /** @var \eZ\Publish\API\Repository\LocationService */
44
    private $locationService;
45
46
    public function setUp(): void
47
    {
48
        parent::setUp();
49
50
        $repository = $this->getRepository();
51
        $this->permissionResolver = $repository->getPermissionResolver();
52
        $this->contentService = $repository->getContentService();
53
        $this->locationService = $repository->getLocationService();
54
    }
55
56
    /**
57
     * Test for the newContentCreateStruct() method.
58
     *
59
     * @see \eZ\Publish\API\Repository\ContentService::newContentCreateStruct()
60
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
61
     * @group user
62
     * @group field-type
63
     */
64
    public function testNewContentCreateStruct()
65
    {
66
        $repository = $this->getRepository();
67
68
        /* BEGIN: Use Case */
69
        // Create a content type
70
        $contentTypeService = $repository->getContentTypeService();
71
72
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
73
74
        $contentService = $repository->getContentService();
75
76
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
77
        /* END: Use Case */
78
79
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct', $contentCreate);
80
    }
81
82
    /**
83
     * Test for the createContent() method.
84
     *
85
     * @return \eZ\Publish\API\Repository\Values\Content\Content
86
     *
87
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
88
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentCreateStruct
89
     * @group user
90
     * @group field-type
91
     */
92
    public function testCreateContent()
93
    {
94
        if ($this->isVersion4()) {
95
            $this->markTestSkipped('This test requires eZ Publish 5');
96
        }
97
98
        $repository = $this->getRepository();
99
100
        /* BEGIN: Use Case */
101
        $contentTypeService = $repository->getContentTypeService();
102
103
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
104
105
        $contentService = $repository->getContentService();
106
107
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
108
        $contentCreate->setField('name', 'My awesome forum');
109
110
        $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
111
        $contentCreate->alwaysAvailable = true;
112
113
        $content = $contentService->createContent($contentCreate);
114
        /* END: Use Case */
115
116
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content', $content);
117
118
        return $content;
119
    }
120
121
    /**
122
     * Test for the createContent() method.
123
     *
124
     * Tests made for issue #EZP-20955 where Anonymous user is granted access to create content
125
     * and should have access to do that.
126
     *
127
     * @return \eZ\Publish\API\Repository\Values\Content\Content
128
     *
129
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
130
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentCreateStruct
131
     * @group user
132
     * @group field-type
133
     */
134
    public function testCreateContentAndPublishWithPrivilegedAnonymousUser()
135
    {
136
        if ($this->isVersion4()) {
137
            $this->markTestSkipped('This test requires eZ Publish 5');
138
        }
139
140
        $anonymousUserId = $this->generateId('user', 10);
141
142
        $repository = $this->getRepository();
143
        $contentService = $repository->getContentService();
144
        $contentTypeService = $repository->getContentTypeService();
145
        $locationService = $repository->getLocationService();
146
        $roleService = $repository->getRoleService();
147
148
        // Give Anonymous user role additional rights
149
        $role = $roleService->loadRoleByIdentifier('Anonymous');
150
        $roleDraft = $roleService->createRoleDraft($role);
151
        $policyCreateStruct = $roleService->newPolicyCreateStruct('content', 'create');
152
        $policyCreateStruct->addLimitation(new SectionLimitation(['limitationValues' => [1]]));
153
        $policyCreateStruct->addLimitation(new LocationLimitation(['limitationValues' => [2]]));
154
        $policyCreateStruct->addLimitation(new ContentTypeLimitation(['limitationValues' => [1]]));
155
        $roleDraft = $roleService->addPolicyByRoleDraft($roleDraft, $policyCreateStruct);
156
157
        $policyCreateStruct = $roleService->newPolicyCreateStruct('content', 'publish');
158
        $policyCreateStruct->addLimitation(new SectionLimitation(['limitationValues' => [1]]));
159
        $policyCreateStruct->addLimitation(new LocationLimitation(['limitationValues' => [2]]));
160
        $policyCreateStruct->addLimitation(new ContentTypeLimitation(['limitationValues' => [1]]));
161
        $roleDraft = $roleService->addPolicyByRoleDraft($roleDraft, $policyCreateStruct);
162
        $roleService->publishRoleDraft($roleDraft);
163
164
        // Set Anonymous user as current
165
        $repository->getPermissionResolver()->setCurrentUserReference($repository->getUserService()->loadUser($anonymousUserId));
166
167
        // Create a new content object:
168
        $contentCreate = $contentService->newContentCreateStruct(
169
            $contentTypeService->loadContentTypeByIdentifier('folder'),
170
            'eng-GB'
171
        );
172
173
        $contentCreate->setField('name', 'Folder 1');
174
175
        $content = $contentService->createContent(
176
            $contentCreate,
177
            [$locationService->newLocationCreateStruct(2)]
178
        );
179
180
        $contentService->publishVersion(
181
            $content->getVersionInfo()
182
        );
183
    }
184
185
    /**
186
     * Test for the createContent() method.
187
     *
188
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
189
     *
190
     * @return \eZ\Publish\API\Repository\Values\Content\Content
191
     *
192
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
193
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
194
     */
195
    public function testCreateContentSetsContentInfo($content)
196
    {
197
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $content->contentInfo);
198
199
        return $content;
200
    }
201
202
    /**
203
     * Test for the createContent() method.
204
     *
205
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
206
     *
207
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
208
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentSetsContentInfo
209
     */
210
    public function testCreateContentSetsExpectedContentInfo($content)
211
    {
212
        $this->assertEquals(
213
            [
214
                $content->id,
215
                28, // id of content type "forum"
216
                true,
217
                1,
218
                'abcdef0123456789abcdef0123456789',
219
                'eng-US',
220
                $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...
221
                false,
222
                null,
223
                // Main Location id for unpublished Content should be null
224
                null,
225
            ],
226
            [
227
                $content->contentInfo->id,
228
                $content->contentInfo->contentTypeId,
229
                $content->contentInfo->alwaysAvailable,
230
                $content->contentInfo->currentVersionNo,
231
                $content->contentInfo->remoteId,
232
                $content->contentInfo->mainLanguageCode,
233
                $content->contentInfo->ownerId,
234
                $content->contentInfo->published,
235
                $content->contentInfo->publishedDate,
236
                $content->contentInfo->mainLocationId,
237
            ]
238
        );
239
    }
240
241
    /**
242
     * Test for the createContent() method.
243
     *
244
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
245
     *
246
     * @return \eZ\Publish\API\Repository\Values\Content\Content
247
     *
248
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
249
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
250
     */
251
    public function testCreateContentSetsVersionInfo($content)
252
    {
253
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo', $content->getVersionInfo());
254
255
        return $content;
256
    }
257
258
    /**
259
     * Test for the createContent() method.
260
     *
261
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
262
     *
263
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
264
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentSetsVersionInfo
265
     */
266
    public function testCreateContentSetsExpectedVersionInfo($content)
267
    {
268
        $this->assertEquals(
269
            [
270
                'status' => VersionInfo::STATUS_DRAFT,
271
                'versionNo' => 1,
272
                '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...
273
                'initialLanguageCode' => 'eng-US',
274
            ],
275
            [
276
                'status' => $content->getVersionInfo()->status,
277
                'versionNo' => $content->getVersionInfo()->versionNo,
278
                'creatorId' => $content->getVersionInfo()->creatorId,
279
                'initialLanguageCode' => $content->getVersionInfo()->initialLanguageCode,
280
            ]
281
        );
282
        $this->assertTrue($content->getVersionInfo()->isDraft());
283
        $this->assertFalse($content->getVersionInfo()->isPublished());
284
        $this->assertFalse($content->getVersionInfo()->isArchived());
285
    }
286
287
    /**
288
     * Test for the createContent() method.
289
     *
290
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
291
     *
292
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
293
     * @depends testCreateContent
294
     */
295
    public function testCreateContentSetsExpectedContentType($content)
296
    {
297
        $contentType = $content->getContentType();
298
299
        $this->assertEquals(
300
            [
301
                $contentType->id,
302
                // Won't match as it's set to true in createContentDraftVersion1()
303
                //$contentType->defaultAlwaysAvailable,
304
                //$contentType->defaultSortField,
305
                //$contentType->defaultSortOrder,
306
            ],
307
            [
308
                $content->contentInfo->contentTypeId,
309
                //$content->contentInfo->alwaysAvailable,
310
                //$location->sortField,
311
                //$location->sortOrder,
312
            ]
313
        );
314
    }
315
316
    /**
317
     * Test for the createContent() method.
318
     *
319
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
320
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
321
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
322
     */
323
    public function testCreateContentThrowsInvalidArgumentException()
324
    {
325
        if ($this->isVersion4()) {
326
            $this->markTestSkipped('This test requires eZ Publish 5');
327
        }
328
329
        $repository = $this->getRepository();
330
331
        /* BEGIN: Use Case */
332
        $contentTypeService = $repository->getContentTypeService();
333
        $contentService = $repository->getContentService();
334
335
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
336
337
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
338
        $contentCreate1->setField('name', 'An awesome Sidelfingen forum');
339
340
        $contentCreate1->remoteId = 'abcdef0123456789abcdef0123456789';
341
        $contentCreate1->alwaysAvailable = true;
342
343
        $draft = $contentService->createContent($contentCreate1);
344
        $contentService->publishVersion($draft->versionInfo);
345
346
        $contentCreate2 = $contentService->newContentCreateStruct($contentType, 'eng-GB');
347
        $contentCreate2->setField('name', 'An awesome Bielefeld forum');
348
349
        $contentCreate2->remoteId = 'abcdef0123456789abcdef0123456789';
350
        $contentCreate2->alwaysAvailable = false;
351
352
        // This call will fail with an "InvalidArgumentException", because the
353
        // remoteId is already in use.
354
        $contentService->createContent($contentCreate2);
355
        /* END: Use Case */
356
    }
357
358
    /**
359
     * Test for the createContent() method.
360
     *
361
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
362
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
363
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
364
     */
365 View Code Duplication
    public function testCreateContentThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
366
    {
367
        $repository = $this->getRepository();
368
369
        /* BEGIN: Use Case */
370
        $contentTypeService = $repository->getContentTypeService();
371
        $contentService = $repository->getContentService();
372
373
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
374
375
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
376
        // The name field does only accept strings and null as its values
377
        $contentCreate->setField('name', new \stdClass());
378
379
        // Throws InvalidArgumentException since the name field is filled
380
        // improperly
381
        $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...
382
        /* END: Use Case */
383
    }
384
385
    /**
386
     * Test for the createContent() method.
387
     *
388
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
389
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
390
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
391
     */
392
    public function testCreateContentThrowsContentFieldValidationException()
393
    {
394
        $repository = $this->getRepository();
395
396
        /* BEGIN: Use Case */
397
        $contentTypeService = $repository->getContentTypeService();
398
        $contentService = $repository->getContentService();
399
400
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
401
402
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
403
        $contentCreate1->setField('name', 'An awesome Sidelfingen folder');
404
        // Violates string length constraint
405
        $contentCreate1->setField('short_name', str_repeat('a', 200));
406
407
        // Throws ContentFieldValidationException, since short_name does not pass
408
        // validation of the string length validator
409
        $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...
410
        /* END: Use Case */
411
    }
412
413
    /**
414
     * Test for the createContent() method.
415
     *
416
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
417
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
418
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
419
     */
420 View Code Duplication
    public function testCreateContentRequiredFieldMissing()
421
    {
422
        $repository = $this->getRepository();
423
424
        /* BEGIN: Use Case */
425
        $contentTypeService = $repository->getContentTypeService();
426
        $contentService = $repository->getContentService();
427
428
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
429
430
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
431
        // Required field "name" is not set
432
433
        // Throws a ContentFieldValidationException, since a required field is
434
        // missing
435
        $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...
436
        /* END: Use Case */
437
    }
438
439
    /**
440
     * Test for the createContent() method.
441
     *
442
     * NOTE: We have bidirectional dependencies between the ContentService and
443
     * the LocationService, so that we cannot use PHPUnit's test dependencies
444
     * here.
445
     *
446
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
447
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
448
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationByRemoteId
449
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
450
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
451
     * @group user
452
     */
453
    public function testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately()
454
    {
455
        $repository = $this->getRepository();
456
457
        $locationService = $repository->getLocationService();
458
459
        /* BEGIN: Use Case */
460
        $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...
461
462
        // The location will not have been created, yet, so this throws an
463
        // exception
464
        $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...
465
            '0123456789abcdef0123456789abcdef'
466
        );
467
        /* END: Use Case */
468
    }
469
470
    /**
471
     * Test for the createContent() method.
472
     *
473
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
474
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
475
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
476
     */
477
    public function testCreateContentThrowsInvalidArgumentExceptionWithLocationCreateParameter()
478
    {
479
        $repository = $this->getRepository();
480
481
        $parentLocationId = $this->generateId('location', 56);
482
        /* BEGIN: Use Case */
483
        // $parentLocationId is a valid location ID
484
485
        $contentService = $repository->getContentService();
486
        $contentTypeService = $repository->getContentTypeService();
487
        $locationService = $repository->getLocationService();
488
489
        // Load content type
490
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
491
492
        // Configure new locations
493
        $locationCreate1 = $locationService->newLocationCreateStruct($parentLocationId);
494
495
        $locationCreate1->priority = 23;
496
        $locationCreate1->hidden = true;
497
        $locationCreate1->remoteId = '0123456789abcdef0123456789aaaaaa';
498
        $locationCreate1->sortField = Location::SORT_FIELD_NODE_ID;
499
        $locationCreate1->sortOrder = Location::SORT_ORDER_DESC;
500
501
        $locationCreate2 = $locationService->newLocationCreateStruct($parentLocationId);
502
503
        $locationCreate2->priority = 42;
504
        $locationCreate2->hidden = true;
505
        $locationCreate2->remoteId = '0123456789abcdef0123456789bbbbbb';
506
        $locationCreate2->sortField = Location::SORT_FIELD_NODE_ID;
507
        $locationCreate2->sortOrder = Location::SORT_ORDER_DESC;
508
509
        // Configure new content object
510
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
511
512
        $contentCreate->setField('name', 'A awesome Sindelfingen forum');
513
        $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
514
        $contentCreate->alwaysAvailable = true;
515
516
        // Create new content object under the specified location
517
        $draft = $contentService->createContent(
518
            $contentCreate,
519
            [$locationCreate1]
520
        );
521
        $contentService->publishVersion($draft->versionInfo);
522
523
        // This call will fail with an "InvalidArgumentException", because the
524
        // Content remoteId already exists,
525
        $contentService->createContent(
526
            $contentCreate,
527
            [$locationCreate2]
528
        );
529
        /* END: Use Case */
530
    }
531
532
    /**
533
     * Test for the loadContentInfo() method.
534
     *
535
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
536
     * @group user
537
     */
538 View Code Duplication
    public function testLoadContentInfo()
539
    {
540
        $repository = $this->getRepository();
541
542
        $mediaFolderId = $this->generateId('object', 41);
543
        /* BEGIN: Use Case */
544
        $contentService = $repository->getContentService();
545
546
        // Load the ContentInfo for "Media" folder
547
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
548
        /* END: Use Case */
549
550
        $this->assertInstanceOf(
551
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo',
552
            $contentInfo
553
        );
554
555
        return $contentInfo;
556
    }
557
558
    /**
559
     * Test for the returned value of the loadContentInfo() method.
560
     *
561
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
562
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentInfo
563
     *
564
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
565
     */
566
    public function testLoadContentInfoSetsExpectedContentInfo(ContentInfo $contentInfo)
567
    {
568
        $this->assertPropertiesCorrectUnsorted(
569
            $this->getExpectedMediaContentInfoProperties(),
570
            $contentInfo
571
        );
572
    }
573
574
    /**
575
     * Test for the loadContentInfo() method.
576
     *
577
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
578
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
579
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
580
     */
581 View Code Duplication
    public function testLoadContentInfoThrowsNotFoundException()
582
    {
583
        $repository = $this->getRepository();
584
585
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
586
        /* BEGIN: Use Case */
587
        $contentService = $repository->getContentService();
588
589
        // This call will fail with a NotFoundException
590
        $contentService->loadContentInfo($nonExistentContentId);
591
        /* END: Use Case */
592
    }
593
594
    /**
595
     * Test for the loadContentInfoList() method.
596
     *
597
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
598
     */
599
    public function testLoadContentInfoList()
600
    {
601
        $repository = $this->getRepository();
602
603
        $mediaFolderId = $this->generateId('object', 41);
604
        $contentService = $repository->getContentService();
605
        $list = $contentService->loadContentInfoList([$mediaFolderId]);
606
607
        $this->assertCount(1, $list);
608
        $this->assertEquals([$mediaFolderId], array_keys($list), 'Array key was not content id');
609
        $this->assertInstanceOf(
610
            ContentInfo::class,
611
            $list[$mediaFolderId]
612
        );
613
    }
614
615
    /**
616
     * Test for the loadContentInfoList() method.
617
     *
618
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
619
     * @depends testLoadContentInfoList
620
     */
621 View Code Duplication
    public function testLoadContentInfoListSkipsNotFoundItems()
622
    {
623
        $repository = $this->getRepository();
624
625
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
626
        $contentService = $repository->getContentService();
627
        $list = $contentService->loadContentInfoList([$nonExistentContentId]);
628
629
        $this->assertCount(0, $list);
630
    }
631
632
    /**
633
     * Test for the loadContentInfoByRemoteId() method.
634
     *
635
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
636
     */
637
    public function testLoadContentInfoByRemoteId()
638
    {
639
        $repository = $this->getRepository();
640
641
        /* BEGIN: Use Case */
642
        $contentService = $repository->getContentService();
643
644
        // Load the ContentInfo for "Media" folder
645
        $contentInfo = $contentService->loadContentInfoByRemoteId('faaeb9be3bd98ed09f606fc16d144eca');
646
        /* END: Use Case */
647
648
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $contentInfo);
649
650
        return $contentInfo;
651
    }
652
653
    /**
654
     * Test for the returned value of the loadContentInfoByRemoteId() method.
655
     *
656
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
657
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId
658
     *
659
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
660
     */
661 View Code Duplication
    public function testLoadContentInfoByRemoteIdSetsExpectedContentInfo(ContentInfo $contentInfo)
662
    {
663
        $this->assertPropertiesCorrectUnsorted(
664
            [
665
                'id' => 10,
666
                'contentTypeId' => 4,
667
                'name' => 'Anonymous User',
668
                'sectionId' => 2,
669
                'currentVersionNo' => 2,
670
                'published' => true,
671
                'ownerId' => 14,
672
                'modificationDate' => $this->createDateTime(1072180405),
673
                'publishedDate' => $this->createDateTime(1033920665),
674
                'alwaysAvailable' => 1,
675
                'remoteId' => 'faaeb9be3bd98ed09f606fc16d144eca',
676
                'mainLanguageCode' => 'eng-US',
677
                'mainLocationId' => 45,
678
            ],
679
            $contentInfo
680
        );
681
    }
682
683
    /**
684
     * Test for the loadContentInfoByRemoteId() method.
685
     *
686
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
687
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
688
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
689
     */
690
    public function testLoadContentInfoByRemoteIdThrowsNotFoundException()
691
    {
692
        $repository = $this->getRepository();
693
694
        /* BEGIN: Use Case */
695
        $contentService = $repository->getContentService();
696
697
        // This call will fail with a NotFoundException
698
        $contentService->loadContentInfoByRemoteId('abcdefghijklmnopqrstuvwxyz0123456789');
699
        /* END: Use Case */
700
    }
701
702
    /**
703
     * Test for the loadVersionInfo() method.
704
     *
705
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo()
706
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
707
     * @group user
708
     */
709 View Code Duplication
    public function testLoadVersionInfo()
710
    {
711
        $repository = $this->getRepository();
712
713
        $mediaFolderId = $this->generateId('object', 41);
714
        /* BEGIN: Use Case */
715
        // $mediaFolderId contains the ID of the "Media" folder
716
717
        $contentService = $repository->getContentService();
718
719
        // Load the ContentInfo for "Media" folder
720
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
721
722
        // Now load the current version info of the "Media" folder
723
        $versionInfo = $contentService->loadVersionInfo($contentInfo);
724
        /* END: Use Case */
725
726
        $this->assertInstanceOf(
727
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo',
728
            $versionInfo
729
        );
730
    }
731
732
    /**
733
     * Test for the loadVersionInfoById() method.
734
     *
735
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
736
     */
737 View Code Duplication
    public function testLoadVersionInfoById()
738
    {
739
        $repository = $this->getRepository();
740
741
        $mediaFolderId = $this->generateId('object', 41);
742
        /* BEGIN: Use Case */
743
        // $mediaFolderId contains the ID of the "Media" folder
744
745
        $contentService = $repository->getContentService();
746
747
        // Load the VersionInfo for "Media" folder
748
        $versionInfo = $contentService->loadVersionInfoById($mediaFolderId);
749
        /* END: Use Case */
750
751
        $this->assertInstanceOf(
752
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo',
753
            $versionInfo
754
        );
755
756
        return $versionInfo;
757
    }
758
759
    /**
760
     * Test for the returned value of the loadVersionInfoById() method.
761
     *
762
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
763
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
764
     *
765
     * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo
766
     */
767
    public function testLoadVersionInfoByIdSetsExpectedVersionInfo(VersionInfo $versionInfo)
768
    {
769
        $this->assertPropertiesCorrect(
770
            [
771
                'names' => [
772
                    'eng-US' => 'Media',
773
                ],
774
                'contentInfo' => new ContentInfo($this->getExpectedMediaContentInfoProperties()),
775
                'id' => 472,
776
                'versionNo' => 1,
777
                'modificationDate' => $this->createDateTime(1060695457),
778
                'creatorId' => 14,
779
                'creationDate' => $this->createDateTime(1060695450),
780
                'status' => VersionInfo::STATUS_PUBLISHED,
781
                'initialLanguageCode' => 'eng-US',
782
                'languageCodes' => [
783
                    'eng-US',
784
                ],
785
            ],
786
            $versionInfo
787
        );
788
        $this->assertTrue($versionInfo->isPublished());
789
        $this->assertFalse($versionInfo->isDraft());
790
        $this->assertFalse($versionInfo->isArchived());
791
    }
792
793
    /**
794
     * Test for the loadVersionInfoById() method.
795
     *
796
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
797
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
798
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
799
     */
800 View Code Duplication
    public function testLoadVersionInfoByIdThrowsNotFoundException()
801
    {
802
        $repository = $this->getRepository();
803
804
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
805
        /* BEGIN: Use Case */
806
        $contentService = $repository->getContentService();
807
808
        // This call will fail with a "NotFoundException"
809
        $contentService->loadVersionInfoById($nonExistentContentId);
810
        /* END: Use Case */
811
    }
812
813
    /**
814
     * Test for the loadContentByContentInfo() method.
815
     *
816
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo()
817
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
818
     */
819 View Code Duplication
    public function testLoadContentByContentInfo()
820
    {
821
        $repository = $this->getRepository();
822
823
        $mediaFolderId = $this->generateId('object', 41);
824
        /* BEGIN: Use Case */
825
        // $mediaFolderId contains the ID of the "Media" folder
826
827
        $contentService = $repository->getContentService();
828
829
        // Load the ContentInfo for "Media" folder
830
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
831
832
        // Now load the current content version for the info instance
833
        $content = $contentService->loadContentByContentInfo($contentInfo);
834
        /* END: Use Case */
835
836
        $this->assertInstanceOf(
837
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
838
            $content
839
        );
840
    }
841
842
    /**
843
     * Test for the loadContentByVersionInfo() method.
844
     *
845
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo()
846
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
847
     */
848 View Code Duplication
    public function testLoadContentByVersionInfo()
849
    {
850
        $repository = $this->getRepository();
851
852
        $mediaFolderId = $this->generateId('object', 41);
853
        /* BEGIN: Use Case */
854
        // $mediaFolderId contains the ID of the "Media" folder
855
856
        $contentService = $repository->getContentService();
857
858
        // Load the ContentInfo for "Media" folder
859
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
860
861
        // Load the current VersionInfo
862
        $versionInfo = $contentService->loadVersionInfo($contentInfo);
863
864
        // Now load the current content version for the info instance
865
        $content = $contentService->loadContentByVersionInfo($versionInfo);
866
        /* END: Use Case */
867
868
        $this->assertInstanceOf(
869
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
870
            $content
871
        );
872
    }
873
874
    /**
875
     * Test for the loadContent() method.
876
     *
877
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
878
     * @group user
879
     * @group field-type
880
     */
881 View Code Duplication
    public function testLoadContent()
882
    {
883
        $repository = $this->getRepository();
884
885
        $mediaFolderId = $this->generateId('object', 41);
886
        /* BEGIN: Use Case */
887
        // $mediaFolderId contains the ID of the "Media" folder
888
889
        $contentService = $repository->getContentService();
890
891
        // Load the Content for "Media" folder, any language and current version
892
        $content = $contentService->loadContent($mediaFolderId);
893
        /* END: Use Case */
894
895
        $this->assertInstanceOf(
896
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
897
            $content
898
        );
899
    }
900
901
    /**
902
     * Test for the loadContent() method.
903
     *
904
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
905
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
906
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
907
     */
908 View Code Duplication
    public function testLoadContentThrowsNotFoundException()
909
    {
910
        $repository = $this->getRepository();
911
912
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
913
        /* BEGIN: Use Case */
914
        $contentService = $repository->getContentService();
915
916
        // This call will fail with a "NotFoundException"
917
        $contentService->loadContent($nonExistentContentId);
918
        /* END: Use Case */
919
    }
920
921
    /**
922
     * Data provider for testLoadContentByRemoteId().
923
     *
924
     * @return array
925
     */
926
    public function contentRemoteIdVersionLanguageProvider()
927
    {
928
        return [
929
            ['f5c88a2209584891056f987fd965b0ba', null, null],
930
            ['f5c88a2209584891056f987fd965b0ba', ['eng-US'], null],
931
            ['f5c88a2209584891056f987fd965b0ba', null, 1],
932
            ['f5c88a2209584891056f987fd965b0ba', ['eng-US'], 1],
933
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', null, null],
934
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', ['eng-US'], null],
935
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', null, 1],
936
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', ['eng-US'], 1],
937
        ];
938
    }
939
940
    /**
941
     * Test for the loadContentByRemoteId() method.
942
     *
943
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId
944
     * @dataProvider contentRemoteIdVersionLanguageProvider
945
     *
946
     * @param string $remoteId
947
     * @param array|null $languages
948
     * @param int $versionNo
949
     */
950
    public function testLoadContentByRemoteId($remoteId, $languages, $versionNo)
951
    {
952
        $repository = $this->getRepository();
953
954
        $contentService = $repository->getContentService();
955
956
        $content = $contentService->loadContentByRemoteId($remoteId, $languages, $versionNo);
957
958
        $this->assertInstanceOf(
959
            Content::class,
960
            $content
961
        );
962
963
        $this->assertEquals($remoteId, $content->contentInfo->remoteId);
964
        if ($languages !== null) {
965
            $this->assertEquals($languages, $content->getVersionInfo()->languageCodes);
966
        }
967
        $this->assertEquals($versionNo ?: 1, $content->getVersionInfo()->versionNo);
968
    }
969
970
    /**
971
     * Test for the loadContentByRemoteId() method.
972
     *
973
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId()
974
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
975
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
976
     */
977
    public function testLoadContentByRemoteIdThrowsNotFoundException()
978
    {
979
        $repository = $this->getRepository();
980
981
        /* BEGIN: Use Case */
982
        $contentService = $repository->getContentService();
983
984
        // This call will fail with a "NotFoundException", because no content
985
        // object exists for the given remoteId
986
        $contentService->loadContentByRemoteId('a1b1c1d1e1f1a2b2c2d2e2f2a3b3c3d3');
987
        /* END: Use Case */
988
    }
989
990
    /**
991
     * Test for the publishVersion() method.
992
     *
993
     * @return \eZ\Publish\API\Repository\Values\Content\Content
994
     *
995
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
996
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
997
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
998
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
999
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
1000
     * @group user
1001
     * @group field-type
1002
     */
1003
    public function testPublishVersion()
1004
    {
1005
        $time = time();
1006
        /* BEGIN: Use Case */
1007
        $content = $this->createContentVersion1();
1008
        /* END: Use Case */
1009
1010
        $this->assertInstanceOf(Content::class, $content);
1011
        $this->assertTrue($content->contentInfo->published);
1012
        $this->assertEquals(VersionInfo::STATUS_PUBLISHED, $content->versionInfo->status);
1013
        $this->assertGreaterThanOrEqual($time, $content->contentInfo->publishedDate->getTimestamp());
1014
        $this->assertGreaterThanOrEqual($time, $content->contentInfo->modificationDate->getTimestamp());
1015
        $this->assertTrue($content->versionInfo->isPublished());
1016
        $this->assertFalse($content->versionInfo->isDraft());
1017
        $this->assertFalse($content->versionInfo->isArchived());
1018
1019
        return $content;
1020
    }
1021
1022
    /**
1023
     * Test for the publishVersion() method.
1024
     *
1025
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1026
     *
1027
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1028
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1029
     */
1030
    public function testPublishVersionSetsExpectedContentInfo($content)
1031
    {
1032
        $this->assertEquals(
1033
            [
1034
                $content->id,
1035
                true,
1036
                1,
1037
                'abcdef0123456789abcdef0123456789',
1038
                'eng-US',
1039
                $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...
1040
                true,
1041
            ],
1042
            [
1043
                $content->contentInfo->id,
1044
                $content->contentInfo->alwaysAvailable,
1045
                $content->contentInfo->currentVersionNo,
1046
                $content->contentInfo->remoteId,
1047
                $content->contentInfo->mainLanguageCode,
1048
                $content->contentInfo->ownerId,
1049
                $content->contentInfo->published,
1050
            ]
1051
        );
1052
1053
        $this->assertNotNull($content->contentInfo->mainLocationId);
1054
        $date = new \DateTime('1984/01/01');
1055
        $this->assertGreaterThan(
1056
            $date->getTimestamp(),
1057
            $content->contentInfo->publishedDate->getTimestamp()
1058
        );
1059
    }
1060
1061
    /**
1062
     * Test for the publishVersion() method.
1063
     *
1064
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1065
     *
1066
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1067
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1068
     */
1069
    public function testPublishVersionSetsExpectedVersionInfo($content)
1070
    {
1071
        $this->assertEquals(
1072
            [
1073
                $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...
1074
                'eng-US',
1075
                VersionInfo::STATUS_PUBLISHED,
1076
                1,
1077
            ],
1078
            [
1079
                $content->getVersionInfo()->creatorId,
1080
                $content->getVersionInfo()->initialLanguageCode,
1081
                $content->getVersionInfo()->status,
1082
                $content->getVersionInfo()->versionNo,
1083
            ]
1084
        );
1085
1086
        $date = new \DateTime('1984/01/01');
1087
        $this->assertGreaterThan(
1088
            $date->getTimestamp(),
1089
            $content->getVersionInfo()->modificationDate->getTimestamp()
1090
        );
1091
1092
        $this->assertNotNull($content->getVersionInfo()->modificationDate);
1093
        $this->assertTrue($content->getVersionInfo()->isPublished());
1094
        $this->assertFalse($content->getVersionInfo()->isDraft());
1095
        $this->assertFalse($content->getVersionInfo()->isArchived());
1096
    }
1097
1098
    /**
1099
     * Test for the publishVersion() method.
1100
     *
1101
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1102
     *
1103
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1104
     * @depends testPublishVersion
1105
     */
1106
    public function testPublishVersionSetsExpectedContentType($content)
1107
    {
1108
        $contentType = $content->getContentType();
1109
1110
        $this->assertEquals(
1111
            [
1112
                $contentType->id,
1113
                // won't be a match as it's set to true in createContentDraftVersion1()
1114
                //$contentType->defaultAlwaysAvailable,
1115
                //$contentType->defaultSortField,
1116
                //$contentType->defaultSortOrder,
1117
            ],
1118
            [
1119
                $content->contentInfo->contentTypeId,
1120
                //$content->contentInfo->alwaysAvailable,
1121
                //$location->sortField,
1122
                //$location->sortOrder,
1123
            ]
1124
        );
1125
    }
1126
1127
    /**
1128
     * Test for the publishVersion() method.
1129
     *
1130
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1131
     *
1132
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1133
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
1134
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1135
     */
1136
    public function testPublishVersionCreatesLocationsDefinedOnCreate()
1137
    {
1138
        $repository = $this->getRepository();
1139
1140
        /* BEGIN: Use Case */
1141
        $content = $this->createContentVersion1();
1142
        /* END: Use Case */
1143
1144
        $locationService = $repository->getLocationService();
1145
        $location = $locationService->loadLocationByRemoteId(
1146
            '0123456789abcdef0123456789abcdef'
1147
        );
1148
1149
        $this->assertEquals(
1150
            $location->getContentInfo(),
1151
            $content->getVersionInfo()->getContentInfo()
1152
        );
1153
1154
        return [$content, $location];
1155
    }
1156
1157
    /**
1158
     * Test for the publishVersion() method.
1159
     *
1160
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1161
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionCreatesLocationsDefinedOnCreate
1162
     */
1163
    public function testCreateContentWithLocationCreateParameterCreatesExpectedLocation(array $testData)
1164
    {
1165
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $content */
1166
        /** @var \eZ\Publish\API\Repository\Values\Content\Location $location */
1167
        list($content, $location) = $testData;
1168
1169
        $parentLocationId = $this->generateId('location', 56);
1170
        $parentLocation = $this->getRepository()->getLocationService()->loadLocation($parentLocationId);
1171
        $mainLocationId = $content->getVersionInfo()->getContentInfo()->mainLocationId;
1172
1173
        $this->assertPropertiesCorrect(
1174
            [
1175
                'id' => $mainLocationId,
1176
                'priority' => 23,
1177
                'hidden' => true,
1178
                'invisible' => true,
1179
                'remoteId' => '0123456789abcdef0123456789abcdef',
1180
                'parentLocationId' => $parentLocationId,
1181
                'pathString' => $parentLocation->pathString . $mainLocationId . '/',
1182
                'depth' => $parentLocation->depth + 1,
1183
                'sortField' => Location::SORT_FIELD_NODE_ID,
1184
                'sortOrder' => Location::SORT_ORDER_DESC,
1185
            ],
1186
            $location
1187
        );
1188
    }
1189
1190
    /**
1191
     * Test for the publishVersion() method.
1192
     *
1193
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1194
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
1195
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1196
     */
1197 View Code Duplication
    public function testPublishVersionThrowsBadStateException()
1198
    {
1199
        $repository = $this->getRepository();
1200
1201
        $contentService = $repository->getContentService();
1202
1203
        /* BEGIN: Use Case */
1204
        $draft = $this->createContentDraftVersion1();
1205
1206
        // Publish the content draft
1207
        $contentService->publishVersion($draft->getVersionInfo());
1208
1209
        // This call will fail with a "BadStateException", because the version
1210
        // is already published.
1211
        $contentService->publishVersion($draft->getVersionInfo());
1212
        /* END: Use Case */
1213
    }
1214
1215
    /**
1216
     * Test that publishVersion() does not affect publishedDate (assuming previous version exists).
1217
     *
1218
     * @covers \eZ\Publish\API\Repository\ContentService::publishVersion
1219
     */
1220
    public function testPublishVersionDoesNotChangePublishedDate()
1221
    {
1222
        $repository = $this->getRepository();
1223
1224
        $contentService = $repository->getContentService();
1225
1226
        $publishedContent = $this->createContentVersion1();
1227
1228
        // force timestamps to differ
1229
        sleep(1);
1230
1231
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
1232
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1233
        $contentUpdateStruct->setField('name', 'New name');
1234
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
1235
        $republishedContent = $contentService->publishVersion($contentDraft->versionInfo);
1236
1237
        $this->assertEquals(
1238
            $publishedContent->contentInfo->publishedDate->getTimestamp(),
1239
            $republishedContent->contentInfo->publishedDate->getTimestamp()
1240
        );
1241
        $this->assertGreaterThan(
1242
            $publishedContent->contentInfo->modificationDate->getTimestamp(),
1243
            $republishedContent->contentInfo->modificationDate->getTimestamp()
1244
        );
1245
    }
1246
1247
    /**
1248
     * Test for the createContentDraft() method.
1249
     *
1250
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1251
     *
1252
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1253
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1254
     * @group user
1255
     */
1256
    public function testCreateContentDraft()
1257
    {
1258
        $repository = $this->getRepository();
1259
1260
        $contentService = $repository->getContentService();
1261
1262
        /* BEGIN: Use Case */
1263
        $content = $this->createContentVersion1();
1264
1265
        // Now we create a new draft from the published content
1266
        $draftedContent = $contentService->createContentDraft($content->contentInfo);
1267
        /* END: Use Case */
1268
1269
        $this->assertInstanceOf(
1270
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1271
            $draftedContent
1272
        );
1273
1274
        return $draftedContent;
1275
    }
1276
1277
    /**
1278
     * Test for the createContentDraft() method.
1279
     *
1280
     * Test that editor has access to edit own draft.
1281
     * Note: Editors have access to version_read, which is needed to load content drafts.
1282
     *
1283
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1284
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1285
     * @group user
1286
     */
1287 View Code Duplication
    public function testCreateContentDraftAndLoadAccess()
1288
    {
1289
        $repository = $this->getRepository();
1290
1291
        /* BEGIN: Use Case */
1292
        $user = $this->createUserVersion1();
1293
1294
        // Set new editor as user
1295
        $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...
1296
1297
        // Create draft
1298
        $draft = $this->createContentDraftVersion1(2, 'folder');
1299
1300
        // Try to load the draft
1301
        $contentService = $repository->getContentService();
1302
        $loadedDraft = $contentService->loadContent($draft->id);
1303
1304
        /* END: Use Case */
1305
1306
        $this->assertEquals($draft->id, $loadedDraft->id);
1307
    }
1308
1309
    /**
1310
     * Test for the createContentDraft() method.
1311
     *
1312
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1313
     *
1314
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1315
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1316
     */
1317
    public function testCreateContentDraftSetsExpectedProperties($draft)
1318
    {
1319
        $this->assertEquals(
1320
            [
1321
                'fieldCount' => 2,
1322
                'relationCount' => 0,
1323
            ],
1324
            [
1325
                'fieldCount' => count($draft->getFields()),
1326
                'relationCount' => count($this->getRepository()->getContentService()->loadRelations($draft->getVersionInfo())),
1327
            ]
1328
        );
1329
    }
1330
1331
    /**
1332
     * Test for the createContentDraft() method.
1333
     *
1334
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1335
     *
1336
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1337
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1338
     */
1339
    public function testCreateContentDraftSetsContentInfo($draft)
1340
    {
1341
        $contentInfo = $draft->contentInfo;
1342
1343
        $this->assertEquals(
1344
            [
1345
                $draft->id,
1346
                true,
1347
                1,
1348
                'eng-US',
1349
                $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...
1350
                'abcdef0123456789abcdef0123456789',
1351
                1,
1352
            ],
1353
            [
1354
                $contentInfo->id,
1355
                $contentInfo->alwaysAvailable,
1356
                $contentInfo->currentVersionNo,
1357
                $contentInfo->mainLanguageCode,
1358
                $contentInfo->ownerId,
1359
                $contentInfo->remoteId,
1360
                $contentInfo->sectionId,
1361
            ]
1362
        );
1363
    }
1364
1365
    /**
1366
     * Test for the createContentDraft() method.
1367
     *
1368
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1369
     *
1370
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1371
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1372
     */
1373
    public function testCreateContentDraftSetsVersionInfo($draft)
1374
    {
1375
        $versionInfo = $draft->getVersionInfo();
1376
1377
        $this->assertEquals(
1378
            [
1379
                '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...
1380
                'initialLanguageCode' => 'eng-US',
1381
                'languageCodes' => [0 => 'eng-US'],
1382
                'status' => VersionInfo::STATUS_DRAFT,
1383
                'versionNo' => 2,
1384
            ],
1385
            [
1386
                'creatorId' => $versionInfo->creatorId,
1387
                'initialLanguageCode' => $versionInfo->initialLanguageCode,
1388
                'languageCodes' => $versionInfo->languageCodes,
1389
                'status' => $versionInfo->status,
1390
                'versionNo' => $versionInfo->versionNo,
1391
            ]
1392
        );
1393
        $this->assertTrue($versionInfo->isDraft());
1394
        $this->assertFalse($versionInfo->isPublished());
1395
        $this->assertFalse($versionInfo->isArchived());
1396
    }
1397
1398
    /**
1399
     * Test for the createContentDraft() method.
1400
     *
1401
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1402
     *
1403
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1404
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1405
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
1406
     */
1407 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...
1408
    {
1409
        $repository = $this->getRepository();
1410
1411
        $contentService = $repository->getContentService();
1412
1413
        /* BEGIN: Use Case */
1414
        $content = $this->createContentVersion1();
1415
1416
        // Now we create a new draft from the published content
1417
        $contentService->createContentDraft($content->contentInfo);
1418
1419
        // This call will still load the published version
1420
        $versionInfoPublished = $contentService->loadVersionInfo($content->contentInfo);
1421
        /* END: Use Case */
1422
1423
        $this->assertEquals(1, $versionInfoPublished->versionNo);
1424
    }
1425
1426
    /**
1427
     * Test for the createContentDraft() method.
1428
     *
1429
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1430
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
1431
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1432
     */
1433 View Code Duplication
    public function testCreateContentDraftLoadContentStillLoadsPublishedVersion()
1434
    {
1435
        $repository = $this->getRepository();
1436
1437
        $contentService = $repository->getContentService();
1438
1439
        /* BEGIN: Use Case */
1440
        $content = $this->createContentVersion1();
1441
1442
        // Now we create a new draft from the published content
1443
        $contentService->createContentDraft($content->contentInfo);
1444
1445
        // This call will still load the published content version
1446
        $contentPublished = $contentService->loadContent($content->id);
1447
        /* END: Use Case */
1448
1449
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1450
    }
1451
1452
    /**
1453
     * Test for the createContentDraft() method.
1454
     *
1455
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1456
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
1457
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1458
     */
1459 View Code Duplication
    public function testCreateContentDraftLoadContentByRemoteIdStillLoadsPublishedVersion()
1460
    {
1461
        $repository = $this->getRepository();
1462
1463
        $contentService = $repository->getContentService();
1464
1465
        /* BEGIN: Use Case */
1466
        $content = $this->createContentVersion1();
1467
1468
        // Now we create a new draft from the published content
1469
        $contentService->createContentDraft($content->contentInfo);
1470
1471
        // This call will still load the published content version
1472
        $contentPublished = $contentService->loadContentByRemoteId('abcdef0123456789abcdef0123456789');
1473
        /* END: Use Case */
1474
1475
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1476
    }
1477
1478
    /**
1479
     * Test for the createContentDraft() method.
1480
     *
1481
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1482
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
1483
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1484
     */
1485 View Code Duplication
    public function testCreateContentDraftLoadContentByContentInfoStillLoadsPublishedVersion()
1486
    {
1487
        $repository = $this->getRepository();
1488
1489
        $contentService = $repository->getContentService();
1490
1491
        /* BEGIN: Use Case */
1492
        $content = $this->createContentVersion1();
1493
1494
        // Now we create a new draft from the published content
1495
        $contentService->createContentDraft($content->contentInfo);
1496
1497
        // This call will still load the published content version
1498
        $contentPublished = $contentService->loadContentByContentInfo($content->contentInfo);
1499
        /* END: Use Case */
1500
1501
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1502
    }
1503
1504
    /**
1505
     * Test for the newContentUpdateStruct() method.
1506
     *
1507
     * @covers \eZ\Publish\API\Repository\ContentService::newContentUpdateStruct
1508
     * @group user
1509
     */
1510
    public function testNewContentUpdateStruct()
1511
    {
1512
        $repository = $this->getRepository();
1513
1514
        /* BEGIN: Use Case */
1515
        $contentService = $repository->getContentService();
1516
1517
        $updateStruct = $contentService->newContentUpdateStruct();
1518
        /* END: Use Case */
1519
1520
        $this->assertInstanceOf(
1521
            ContentUpdateStruct::class,
1522
            $updateStruct
1523
        );
1524
1525
        $this->assertPropertiesCorrect(
1526
            [
1527
                'initialLanguageCode' => null,
1528
                'fields' => [],
1529
            ],
1530
            $updateStruct
1531
        );
1532
    }
1533
1534
    /**
1535
     * Test for the updateContent() method.
1536
     *
1537
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1538
     *
1539
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1540
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentUpdateStruct
1541
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1542
     * @group user
1543
     * @group field-type
1544
     */
1545
    public function testUpdateContent()
1546
    {
1547
        /* BEGIN: Use Case */
1548
        $draftVersion2 = $this->createUpdatedDraftVersion2();
1549
        /* END: Use Case */
1550
1551
        $this->assertInstanceOf(
1552
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1553
            $draftVersion2
1554
        );
1555
1556
        $this->assertEquals(
1557
            $this->generateId('user', 10),
1558
            $draftVersion2->versionInfo->creatorId,
1559
            'creatorId is not properly set on new Version'
1560
        );
1561
1562
        return $draftVersion2;
1563
    }
1564
1565
    /**
1566
     * Test for the updateContent_WithDifferentUser() method.
1567
     *
1568
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1569
     *
1570
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1571
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentUpdateStruct
1572
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1573
     * @group user
1574
     * @group field-type
1575
     */
1576
    public function testUpdateContentWithDifferentUser()
1577
    {
1578
        /* BEGIN: Use Case */
1579
        $arrayWithDraftVersion2 = $this->createUpdatedDraftVersion2NotAdmin();
1580
        /* END: Use Case */
1581
1582
        $this->assertInstanceOf(
1583
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1584
            $arrayWithDraftVersion2[0]
1585
        );
1586
1587
        $this->assertEquals(
1588
            $this->generateId('user', $arrayWithDraftVersion2[1]),
1589
            $arrayWithDraftVersion2[0]->versionInfo->creatorId,
1590
            'creatorId is not properly set on new Version'
1591
        );
1592
1593
        return $arrayWithDraftVersion2[0];
1594
    }
1595
1596
    /**
1597
     * Test for the updateContent() method.
1598
     *
1599
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1600
     *
1601
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1602
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1603
     */
1604
    public function testUpdateContentSetsExpectedFields($content)
1605
    {
1606
        $actual = $this->normalizeFields($content->getFields());
1607
1608
        $expected = [
1609
            new Field(
1610
                [
1611
                    'id' => 0,
1612
                    'value' => true,
1613
                    'languageCode' => 'eng-GB',
1614
                    'fieldDefIdentifier' => 'description',
1615
                    'fieldTypeIdentifier' => 'ezrichtext',
1616
                ]
1617
            ),
1618
            new Field(
1619
                [
1620
                    'id' => 0,
1621
                    'value' => true,
1622
                    'languageCode' => 'eng-US',
1623
                    'fieldDefIdentifier' => 'description',
1624
                    'fieldTypeIdentifier' => 'ezrichtext',
1625
                ]
1626
            ),
1627
            new Field(
1628
                [
1629
                    'id' => 0,
1630
                    'value' => true,
1631
                    'languageCode' => 'eng-GB',
1632
                    'fieldDefIdentifier' => 'name',
1633
                    'fieldTypeIdentifier' => 'ezstring',
1634
                ]
1635
            ),
1636
            new Field(
1637
                [
1638
                    'id' => 0,
1639
                    'value' => true,
1640
                    'languageCode' => 'eng-US',
1641
                    'fieldDefIdentifier' => 'name',
1642
                    'fieldTypeIdentifier' => 'ezstring',
1643
                ]
1644
            ),
1645
        ];
1646
1647
        $this->assertEquals($expected, $actual);
1648
    }
1649
1650
    /**
1651
     * Test for the updateContent() method.
1652
     *
1653
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1654
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
1655
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1656
     */
1657 View Code Duplication
    public function testUpdateContentThrowsBadStateException()
1658
    {
1659
        $repository = $this->getRepository();
1660
1661
        $contentService = $repository->getContentService();
1662
1663
        /* BEGIN: Use Case */
1664
        $content = $this->createContentVersion1();
1665
1666
        // Now create an update struct and modify some fields
1667
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1668
        $contentUpdateStruct->setField('title', 'An awesome² story about ezp.');
1669
        $contentUpdateStruct->setField('title', 'An awesome²³ story about ezp.', 'eng-GB');
1670
1671
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1672
1673
        // This call will fail with a "BadStateException", because $publishedContent
1674
        // is not a draft.
1675
        $contentService->updateContent(
1676
            $content->getVersionInfo(),
1677
            $contentUpdateStruct
1678
        );
1679
        /* END: Use Case */
1680
    }
1681
1682
    /**
1683
     * Test for the updateContent() method.
1684
     *
1685
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1686
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1687
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1688
     */
1689 View Code Duplication
    public function testUpdateContentThrowsInvalidArgumentExceptionWhenFieldTypeDoesNotAccept()
1690
    {
1691
        $repository = $this->getRepository();
1692
1693
        $contentService = $repository->getContentService();
1694
1695
        /* BEGIN: Use Case */
1696
        $draft = $this->createContentDraftVersion1();
1697
1698
        // Now create an update struct and modify some fields
1699
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1700
        // The name field does not accept a stdClass object as its input
1701
        $contentUpdateStruct->setField('name', new \stdClass(), 'eng-US');
1702
1703
        // Throws an InvalidArgumentException, since the value for field "name"
1704
        // is not accepted
1705
        $contentService->updateContent(
1706
            $draft->getVersionInfo(),
1707
            $contentUpdateStruct
1708
        );
1709
        /* END: Use Case */
1710
    }
1711
1712
    /**
1713
     * Test for the updateContent() method.
1714
     *
1715
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1716
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
1717
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1718
     */
1719 View Code Duplication
    public function testUpdateContentWhenMandatoryFieldIsEmpty()
1720
    {
1721
        $repository = $this->getRepository();
1722
1723
        $contentService = $repository->getContentService();
1724
1725
        /* BEGIN: Use Case */
1726
        $draft = $this->createContentDraftVersion1();
1727
1728
        // Now create an update struct and set a mandatory field to null
1729
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1730
        $contentUpdateStruct->setField('name', null);
1731
1732
        // Don't set this, then the above call without languageCode will fail
1733
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1734
1735
        // This call will fail with a "ContentFieldValidationException", because the
1736
        // mandatory "name" field is empty.
1737
        $contentService->updateContent(
1738
            $draft->getVersionInfo(),
1739
            $contentUpdateStruct
1740
        );
1741
        /* END: Use Case */
1742
    }
1743
1744
    /**
1745
     * Test for the updateContent() method.
1746
     *
1747
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1748
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
1749
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1750
     */
1751
    public function testUpdateContentThrowsContentFieldValidationException()
1752
    {
1753
        $repository = $this->getRepository();
1754
1755
        /* BEGIN: Use Case */
1756
        $contentTypeService = $repository->getContentTypeService();
1757
        $contentService = $repository->getContentService();
1758
1759
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1760
1761
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
1762
        $contentCreate->setField('name', 'An awesome Sidelfingen folder');
1763
1764
        $draft = $contentService->createContent($contentCreate);
1765
1766
        $contentUpdate = $contentService->newContentUpdateStruct();
1767
        // Violates string length constraint
1768
        $contentUpdate->setField('short_name', str_repeat('a', 200), 'eng-US');
1769
1770
        // Throws ContentFieldValidationException because the string length
1771
        // validation of the field "short_name" fails
1772
        $contentService->updateContent($draft->getVersionInfo(), $contentUpdate);
1773
        /* END: Use Case */
1774
    }
1775
1776
    /**
1777
     * Test for the updateContent() method.
1778
     *
1779
     * @covers \eZ\Publish\API\Repository\ContentService::updateContent()
1780
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1781
     */
1782
    public function testUpdateContentValidatorIgnoresRequiredFieldsOfNotUpdatedLanguages()
1783
    {
1784
        $repository = $this->getRepository();
1785
        /* BEGIN: Use Case */
1786
        $contentTypeService = $repository->getContentTypeService();
1787
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1788
1789
        // Create multilangual content
1790
        $contentService = $repository->getContentService();
1791
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
1792
        $contentCreate->setField('name', 'An awesome Sidelfingen folder', 'eng-US');
1793
        $contentCreate->setField('name', 'An awesome Sidelfingen folder', 'eng-GB');
1794
1795
        $contentDraft = $contentService->createContent($contentCreate);
1796
1797
        // 2. Update content type definition
1798
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1799
1800
        $fieldDefinition = $contentType->getFieldDefinition('description');
1801
        $fieldDefinitionUpdate = $contentTypeService->newFieldDefinitionUpdateStruct();
1802
        $fieldDefinitionUpdate->identifier = 'description';
1803
        $fieldDefinitionUpdate->isRequired = true;
1804
1805
        $contentTypeService->updateFieldDefinition(
1806
            $contentTypeDraft,
1807
            $fieldDefinition,
1808
            $fieldDefinitionUpdate
1809
        );
1810
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1811
1812
        // 3. Update only eng-US translation
1813
        $description = new DOMDocument();
1814
        $description->loadXML(<<<XML
1815
<?xml version="1.0" encoding="UTF-8"?>
1816
<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">
1817
    <para>Lorem ipsum dolor</para>
1818
</section>
1819
XML
1820
        );
1821
1822
        $contentUpdate = $contentService->newContentUpdateStruct();
1823
        $contentUpdate->setField('name', 'An awesome Sidelfingen folder (updated)', 'eng-US');
1824
        $contentUpdate->setField('description', $description);
1825
1826
        $contentService->updateContent($contentDraft->getVersionInfo(), $contentUpdate);
1827
        /* END: Use Case */
1828
    }
1829
1830
    /**
1831
     * Test for the updateContent() method.
1832
     *
1833
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1834
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1835
     */
1836
    public function testUpdateContentWithNotUpdatingMandatoryField()
1837
    {
1838
        $repository = $this->getRepository();
1839
1840
        $contentService = $repository->getContentService();
1841
1842
        /* BEGIN: Use Case */
1843
        $draft = $this->createContentDraftVersion1();
1844
1845
        // Now create an update struct which does not overwrite mandatory
1846
        // fields
1847
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1848
        $contentUpdateStruct->setField(
1849
            'description',
1850
            '<?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"/>'
1851
        );
1852
1853
        // Don't set this, then the above call without languageCode will fail
1854
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1855
1856
        // This will only update the "description" field in the "eng-US"
1857
        // language
1858
        $updatedDraft = $contentService->updateContent(
1859
            $draft->getVersionInfo(),
1860
            $contentUpdateStruct
1861
        );
1862
        /* END: Use Case */
1863
1864
        foreach ($updatedDraft->getFields() as $field) {
1865
            if ($field->languageCode === 'eng-US' && $field->fieldDefIdentifier === 'name' && $field->value !== null) {
1866
                // Found field
1867
                return;
1868
            }
1869
        }
1870
        $this->fail(
1871
            'Field with identifier "name" in language "eng-US" could not be found or has empty value.'
1872
        );
1873
    }
1874
1875
    /**
1876
     * Test for the createContentDraft() method.
1877
     *
1878
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft($contentInfo, $versionInfo)
1879
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1880
     */
1881 View Code Duplication
    public function testCreateContentDraftWithSecondParameter()
1882
    {
1883
        $repository = $this->getRepository();
1884
1885
        $contentService = $repository->getContentService();
1886
1887
        /* BEGIN: Use Case */
1888
        $contentVersion2 = $this->createContentVersion2();
1889
1890
        // Now we create a new draft from the initial version
1891
        $draftedContentReloaded = $contentService->createContentDraft(
1892
            $contentVersion2->contentInfo,
1893
            $contentVersion2->getVersionInfo()
1894
        );
1895
        /* END: Use Case */
1896
1897
        $this->assertEquals(3, $draftedContentReloaded->getVersionInfo()->versionNo);
1898
    }
1899
1900
    /**
1901
     * Test for the createContentDraft() method with third parameter.
1902
     *
1903
     * @covers \eZ\Publish\Core\Repository\ContentService::createContentDraft
1904
     */
1905 View Code Duplication
    public function testCreateContentDraftWithThirdParameter()
1906
    {
1907
        $repository = $this->getRepository();
1908
1909
        $contentService = $repository->getContentService();
1910
1911
        $content = $contentService->loadContent(4);
1912
        $user = $this->createUserVersion1();
1913
1914
        $draftContent = $contentService->createContentDraft(
1915
            $content->contentInfo,
1916
            $content->getVersionInfo(),
1917
            $user
1918
        );
1919
1920
        $this->assertInstanceOf(
1921
            Content::class,
1922
            $draftContent
1923
        );
1924
    }
1925
1926
    /**
1927
     * Test for the publishVersion() method.
1928
     *
1929
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1930
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1931
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1932
     */
1933 View Code Duplication
    public function testPublishVersionFromContentDraft()
1934
    {
1935
        $repository = $this->getRepository();
1936
1937
        $contentService = $repository->getContentService();
1938
1939
        /* BEGIN: Use Case */
1940
        $contentVersion2 = $this->createContentVersion2();
1941
        /* END: Use Case */
1942
1943
        $versionInfo = $contentService->loadVersionInfo($contentVersion2->contentInfo);
1944
1945
        $this->assertEquals(
1946
            [
1947
                'status' => VersionInfo::STATUS_PUBLISHED,
1948
                'versionNo' => 2,
1949
            ],
1950
            [
1951
                'status' => $versionInfo->status,
1952
                'versionNo' => $versionInfo->versionNo,
1953
            ]
1954
        );
1955
        $this->assertTrue($versionInfo->isPublished());
1956
        $this->assertFalse($versionInfo->isDraft());
1957
        $this->assertFalse($versionInfo->isArchived());
1958
    }
1959
1960
    /**
1961
     * Test for the publishVersion() method.
1962
     *
1963
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1964
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1965
     */
1966 View Code Duplication
    public function testPublishVersionFromContentDraftArchivesOldVersion()
1967
    {
1968
        $repository = $this->getRepository();
1969
1970
        $contentService = $repository->getContentService();
1971
1972
        /* BEGIN: Use Case */
1973
        $contentVersion2 = $this->createContentVersion2();
1974
        /* END: Use Case */
1975
1976
        $versionInfo = $contentService->loadVersionInfo($contentVersion2->contentInfo, 1);
1977
1978
        $this->assertEquals(
1979
            [
1980
                'status' => VersionInfo::STATUS_ARCHIVED,
1981
                'versionNo' => 1,
1982
            ],
1983
            [
1984
                'status' => $versionInfo->status,
1985
                'versionNo' => $versionInfo->versionNo,
1986
            ]
1987
        );
1988
        $this->assertTrue($versionInfo->isArchived());
1989
        $this->assertFalse($versionInfo->isDraft());
1990
        $this->assertFalse($versionInfo->isPublished());
1991
    }
1992
1993
    /**
1994
     * Test for the publishVersion() method.
1995
     *
1996
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1997
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1998
     */
1999
    public function testPublishVersionFromContentDraftUpdatesContentInfoCurrentVersion()
2000
    {
2001
        /* BEGIN: Use Case */
2002
        $contentVersion2 = $this->createContentVersion2();
2003
        /* END: Use Case */
2004
2005
        $this->assertEquals(2, $contentVersion2->contentInfo->currentVersionNo);
2006
    }
2007
2008
    /**
2009
     * Test for the publishVersion() method.
2010
     *
2011
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
2012
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2013
     */
2014 View Code Duplication
    public function testPublishVersionFromOldContentDraftArchivesNewerVersionNo()
2015
    {
2016
        $repository = $this->getRepository();
2017
2018
        $contentService = $repository->getContentService();
2019
2020
        /* BEGIN: Use Case */
2021
        $content = $this->createContentVersion1();
2022
2023
        // Create a new draft with versionNo = 2
2024
        $draftedContentVersion2 = $contentService->createContentDraft($content->contentInfo);
2025
2026
        // Create another new draft with versionNo = 3
2027
        $draftedContentVersion3 = $contentService->createContentDraft($content->contentInfo);
2028
2029
        // Publish draft with versionNo = 3
2030
        $contentService->publishVersion($draftedContentVersion3->getVersionInfo());
2031
2032
        // Publish the first draft with versionNo = 2
2033
        // currentVersionNo is now 2, versionNo 3 will be archived
2034
        $publishedDraft = $contentService->publishVersion($draftedContentVersion2->getVersionInfo());
2035
        /* END: Use Case */
2036
2037
        $this->assertEquals(2, $publishedDraft->contentInfo->currentVersionNo);
2038
    }
2039
2040
    /**
2041
     * Test for the publishVersion() method, and that it creates limited archives.
2042
     *
2043
     * @todo Adapt this when per content type archive limited is added on repository Content Type model.
2044
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
2045
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2046
     */
2047
    public function testPublishVersionNotCreatingUnlimitedArchives()
2048
    {
2049
        $repository = $this->getRepository();
2050
2051
        $contentService = $repository->getContentService();
2052
2053
        $content = $this->createContentVersion1();
2054
2055
        // load first to make sure list gets updated also (cache)
2056
        $versionInfoList = $contentService->loadVersions($content->contentInfo);
2057
        $this->assertEquals(1, count($versionInfoList));
2058
        $this->assertEquals(1, $versionInfoList[0]->versionNo);
2059
2060
        // Create a new draft with versionNo = 2
2061
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2062
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2063
2064
        // Create a new draft with versionNo = 3
2065
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2066
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2067
2068
        // Create a new draft with versionNo = 4
2069
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2070
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2071
2072
        // Create a new draft with versionNo = 5
2073
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2074
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2075
2076
        // Create a new draft with versionNo = 6
2077
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2078
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2079
2080
        // Create a new draft with versionNo = 7
2081
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2082
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2083
2084
        $versionInfoList = $contentService->loadVersions($content->contentInfo);
2085
2086
        $this->assertEquals(6, count($versionInfoList));
2087
        $this->assertEquals(2, $versionInfoList[0]->versionNo);
2088
        $this->assertEquals(7, $versionInfoList[5]->versionNo);
2089
2090
        $this->assertEquals(
2091
            [
2092
                VersionInfo::STATUS_ARCHIVED,
2093
                VersionInfo::STATUS_ARCHIVED,
2094
                VersionInfo::STATUS_ARCHIVED,
2095
                VersionInfo::STATUS_ARCHIVED,
2096
                VersionInfo::STATUS_ARCHIVED,
2097
                VersionInfo::STATUS_PUBLISHED,
2098
            ],
2099
            [
2100
                $versionInfoList[0]->status,
2101
                $versionInfoList[1]->status,
2102
                $versionInfoList[2]->status,
2103
                $versionInfoList[3]->status,
2104
                $versionInfoList[4]->status,
2105
                $versionInfoList[5]->status,
2106
            ]
2107
        );
2108
    }
2109
2110
    /**
2111
     * Test for the newContentMetadataUpdateStruct() method.
2112
     *
2113
     * @covers \eZ\Publish\API\Repository\ContentService::newContentMetadataUpdateStruct
2114
     * @group user
2115
     */
2116
    public function testNewContentMetadataUpdateStruct()
2117
    {
2118
        $repository = $this->getRepository();
2119
2120
        /* BEGIN: Use Case */
2121
        $contentService = $repository->getContentService();
2122
2123
        // Creates a new metadata update struct
2124
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2125
2126
        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...
2127
            $this->assertNull($propertyValue, "Property '{$propertyName}' initial value should be null'");
2128
        }
2129
2130
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
2131
        $metadataUpdate->mainLanguageCode = 'eng-GB';
2132
        $metadataUpdate->alwaysAvailable = false;
2133
        /* END: Use Case */
2134
2135
        $this->assertInstanceOf(
2136
            ContentMetadataUpdateStruct::class,
2137
            $metadataUpdate
2138
        );
2139
    }
2140
2141
    /**
2142
     * Test for the updateContentMetadata() method.
2143
     *
2144
     * @return \eZ\Publish\API\Repository\Values\Content\Content
2145
     *
2146
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2147
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
2148
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentMetadataUpdateStruct
2149
     * @group user
2150
     */
2151
    public function testUpdateContentMetadata()
2152
    {
2153
        $repository = $this->getRepository();
2154
2155
        $contentService = $repository->getContentService();
2156
2157
        /* BEGIN: Use Case */
2158
        $content = $this->createContentVersion1();
2159
2160
        // Creates a metadata update struct
2161
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2162
2163
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
2164
        $metadataUpdate->mainLanguageCode = 'eng-GB';
2165
        $metadataUpdate->alwaysAvailable = false;
2166
        $metadataUpdate->publishedDate = $this->createDateTime(441759600); // 1984/01/01
2167
        $metadataUpdate->modificationDate = $this->createDateTime(441759600); // 1984/01/01
2168
2169
        // Update the metadata of the published content object
2170
        $content = $contentService->updateContentMetadata(
2171
            $content->contentInfo,
2172
            $metadataUpdate
2173
        );
2174
        /* END: Use Case */
2175
2176
        $this->assertInstanceOf(
2177
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
2178
            $content
2179
        );
2180
2181
        return $content;
2182
    }
2183
2184
    /**
2185
     * Test for the updateContentMetadata() method.
2186
     *
2187
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
2188
     *
2189
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2190
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2191
     */
2192
    public function testUpdateContentMetadataSetsExpectedProperties($content)
2193
    {
2194
        $contentInfo = $content->contentInfo;
2195
2196
        $this->assertEquals(
2197
            [
2198
                'remoteId' => 'aaaabbbbccccddddeeeeffff11112222',
2199
                'sectionId' => $this->generateId('section', 1),
2200
                'alwaysAvailable' => false,
2201
                'currentVersionNo' => 1,
2202
                'mainLanguageCode' => 'eng-GB',
2203
                'modificationDate' => $this->createDateTime(441759600),
2204
                '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...
2205
                'published' => true,
2206
                'publishedDate' => $this->createDateTime(441759600),
2207
            ],
2208
            [
2209
                'remoteId' => $contentInfo->remoteId,
2210
                'sectionId' => $contentInfo->sectionId,
2211
                'alwaysAvailable' => $contentInfo->alwaysAvailable,
2212
                'currentVersionNo' => $contentInfo->currentVersionNo,
2213
                'mainLanguageCode' => $contentInfo->mainLanguageCode,
2214
                'modificationDate' => $contentInfo->modificationDate,
2215
                'ownerId' => $contentInfo->ownerId,
2216
                'published' => $contentInfo->published,
2217
                'publishedDate' => $contentInfo->publishedDate,
2218
            ]
2219
        );
2220
    }
2221
2222
    /**
2223
     * Test for the updateContentMetadata() method.
2224
     *
2225
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
2226
     *
2227
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2228
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2229
     */
2230
    public function testUpdateContentMetadataNotUpdatesContentVersion($content)
2231
    {
2232
        $this->assertEquals(1, $content->getVersionInfo()->versionNo);
2233
    }
2234
2235
    /**
2236
     * Test for the updateContentMetadata() method.
2237
     *
2238
     * @covers \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2239
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2240
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2241
     */
2242
    public function testUpdateContentMetadataThrowsInvalidArgumentExceptionOnDuplicateRemoteId()
2243
    {
2244
        $repository = $this->getRepository();
2245
2246
        $contentService = $repository->getContentService();
2247
2248
        /* BEGIN: Use Case */
2249
        // RemoteId of the "Media" page of an eZ Publish demo installation
2250
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2251
2252
        $content = $this->createContentVersion1();
2253
2254
        // Creates a metadata update struct
2255
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2256
        $metadataUpdate->remoteId = $mediaRemoteId;
2257
2258
        // This call will fail with an "InvalidArgumentException", because the
2259
        // specified remoteId is already used by the "Media" page.
2260
        $contentService->updateContentMetadata(
2261
            $content->contentInfo,
2262
            $metadataUpdate
2263
        );
2264
        /* END: Use Case */
2265
    }
2266
2267
    /**
2268
     * Test for the updateContentMetadata() method.
2269
     *
2270
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContentMetadata
2271
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2272
     */
2273
    public function testUpdateContentMetadataThrowsInvalidArgumentExceptionOnNoMetadataPropertiesSet()
2274
    {
2275
        $repository = $this->getRepository();
2276
2277
        $contentService = $repository->getContentService();
2278
2279
        $contentInfo = $contentService->loadContentInfo(4);
2280
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2281
2282
        // Throws an exception because no properties are set in $contentMetadataUpdateStruct
2283
        $contentService->updateContentMetadata($contentInfo, $contentMetadataUpdateStruct);
2284
    }
2285
2286
    /**
2287
     * Test for the deleteContent() method.
2288
     *
2289
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
2290
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2291
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2292
     */
2293 View Code Duplication
    public function testDeleteContent()
2294
    {
2295
        $repository = $this->getRepository();
2296
2297
        $contentService = $repository->getContentService();
2298
        $locationService = $repository->getLocationService();
2299
2300
        /* BEGIN: Use Case */
2301
        $contentVersion2 = $this->createContentVersion2();
2302
2303
        // Load the locations for this content object
2304
        $locations = $locationService->loadLocations($contentVersion2->contentInfo);
2305
2306
        // This will delete the content, all versions and the associated locations
2307
        $contentService->deleteContent($contentVersion2->contentInfo);
2308
        /* END: Use Case */
2309
2310
        foreach ($locations as $location) {
2311
            $locationService->loadLocation($location->id);
2312
        }
2313
    }
2314
2315
    /**
2316
     * Test for the deleteContent() method.
2317
     *
2318
     * Test for issue EZP-21057:
2319
     * "contentService: Unable to delete a content with an empty file attribute"
2320
     *
2321
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
2322
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2323
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2324
     */
2325 View Code Duplication
    public function testDeleteContentWithEmptyBinaryField()
2326
    {
2327
        $repository = $this->getRepository();
2328
2329
        $contentService = $repository->getContentService();
2330
        $locationService = $repository->getLocationService();
2331
2332
        /* BEGIN: Use Case */
2333
        $contentVersion = $this->createContentVersion1EmptyBinaryField();
2334
2335
        // Load the locations for this content object
2336
        $locations = $locationService->loadLocations($contentVersion->contentInfo);
2337
2338
        // This will delete the content, all versions and the associated locations
2339
        $contentService->deleteContent($contentVersion->contentInfo);
2340
        /* END: Use Case */
2341
2342
        foreach ($locations as $location) {
2343
            $locationService->loadLocation($location->id);
2344
        }
2345
    }
2346
2347
    /**
2348
     * Test for the loadContentDrafts() method.
2349
     *
2350
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
2351
     */
2352
    public function testLoadContentDraftsReturnsEmptyArrayByDefault()
2353
    {
2354
        /* BEGIN: Use Case */
2355
        $contentDrafts = $this->contentService->loadContentDrafts();
2356
        /* END: Use Case */
2357
2358
        $this->assertSame([], $contentDrafts);
2359
    }
2360
2361
    /**
2362
     * Test for the loadContentDrafts() method.
2363
     *
2364
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
2365
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
2366
     */
2367
    public function testLoadContentDrafts()
2368
    {
2369
        /* BEGIN: Use Case */
2370
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
2371
        // of a eZ Publish demo installation.
2372
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2373
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
2374
2375
        // "Media" content object
2376
        $mediaContentInfo = $this->contentService->loadContentInfoByRemoteId($mediaRemoteId);
2377
2378
        // "eZ Publish Demo Design ..." content object
2379
        $demoDesignContentInfo = $this->contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
2380
2381
        // Create some drafts
2382
        $this->contentService->createContentDraft($mediaContentInfo);
2383
        $this->contentService->createContentDraft($demoDesignContentInfo);
2384
2385
        // Now $contentDrafts should contain two drafted versions
2386
        $draftedVersions = $this->contentService->loadContentDrafts();
2387
        /* END: Use Case */
2388
2389
        $actual = [
2390
            $draftedVersions[0]->status,
2391
            $draftedVersions[0]->getContentInfo()->remoteId,
2392
            $draftedVersions[1]->status,
2393
            $draftedVersions[1]->getContentInfo()->remoteId,
2394
        ];
2395
        sort($actual, SORT_STRING);
2396
2397
        $this->assertEquals(
2398
            [
2399
                VersionInfo::STATUS_DRAFT,
2400
                VersionInfo::STATUS_DRAFT,
2401
                $demoDesignRemoteId,
2402
                $mediaRemoteId,
2403
            ],
2404
            $actual
2405
        );
2406
    }
2407
2408
    /**
2409
     * Test for the loadContentDrafts() method.
2410
     *
2411
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts($user)
2412
     */
2413
    public function testLoadContentDraftsWithFirstParameter()
2414
    {
2415
        /* BEGIN: Use Case */
2416
        $user = $this->createUserVersion1();
2417
2418
        // Get current user
2419
        $oldCurrentUser = $this->permissionResolver->getCurrentUserReference();
2420
2421
        // Set new editor as user
2422
        $this->permissionResolver->setCurrentUserReference($user);
2423
2424
        // Remote id of the "Media" content object in an eZ Publish demo installation.
2425
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2426
2427
        // "Media" content object
2428
        $mediaContentInfo = $this->contentService->loadContentInfoByRemoteId($mediaRemoteId);
2429
2430
        // Create a content draft
2431
        $this->contentService->createContentDraft($mediaContentInfo);
2432
2433
        // Reset to previous current user
2434
        $this->permissionResolver->setCurrentUserReference($oldCurrentUser);
2435
2436
        // Now $contentDrafts for the previous current user and the new user
2437
        $newCurrentUserDrafts = $this->contentService->loadContentDrafts($user);
2438
        $oldCurrentUserDrafts = $this->contentService->loadContentDrafts();
2439
        /* END: Use Case */
2440
2441
        $this->assertSame([], $oldCurrentUserDrafts);
2442
2443
        $this->assertEquals(
2444
            [
2445
                VersionInfo::STATUS_DRAFT,
2446
                $mediaRemoteId,
2447
            ],
2448
            [
2449
                $newCurrentUserDrafts[0]->status,
2450
                $newCurrentUserDrafts[0]->getContentInfo()->remoteId,
2451
            ]
2452
        );
2453
        $this->assertTrue($newCurrentUserDrafts[0]->isDraft());
2454
        $this->assertFalse($newCurrentUserDrafts[0]->isArchived());
2455
        $this->assertFalse($newCurrentUserDrafts[0]->isPublished());
2456
    }
2457
2458
    /**
2459
     * Test for the loadVersionInfo() method.
2460
     *
2461
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
2462
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2463
     */
2464
    public function testLoadVersionInfoWithSecondParameter()
2465
    {
2466
        $repository = $this->getRepository();
2467
2468
        $contentService = $repository->getContentService();
2469
2470
        /* BEGIN: Use Case */
2471
        $publishedContent = $this->createContentVersion1();
2472
2473
        $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...
2474
2475
        // Will return the VersionInfo of the $draftContent
2476
        $versionInfo = $contentService->loadVersionInfoById($publishedContent->id, 2);
2477
        /* END: Use Case */
2478
2479
        $this->assertEquals(2, $versionInfo->versionNo);
2480
2481
        // Check that ContentInfo contained in VersionInfo has correct main Location id set
2482
        $this->assertEquals(
2483
            $publishedContent->getVersionInfo()->getContentInfo()->mainLocationId,
2484
            $versionInfo->getContentInfo()->mainLocationId
2485
        );
2486
    }
2487
2488
    /**
2489
     * Test for the loadVersionInfo() method.
2490
     *
2491
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
2492
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2493
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
2494
     */
2495
    public function testLoadVersionInfoThrowsNotFoundExceptionWithSecondParameter()
2496
    {
2497
        $repository = $this->getRepository();
2498
2499
        $contentService = $repository->getContentService();
2500
2501
        /* BEGIN: Use Case */
2502
        $draft = $this->createContentDraftVersion1();
2503
2504
        // This call will fail with a "NotFoundException", because not versionNo
2505
        // 2 exists for this content object.
2506
        $contentService->loadVersionInfo($draft->contentInfo, 2);
2507
        /* END: Use Case */
2508
    }
2509
2510
    /**
2511
     * Test for the loadVersionInfoById() method.
2512
     *
2513
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
2514
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
2515
     */
2516
    public function testLoadVersionInfoByIdWithSecondParameter()
2517
    {
2518
        $repository = $this->getRepository();
2519
2520
        $contentService = $repository->getContentService();
2521
2522
        /* BEGIN: Use Case */
2523
        $publishedContent = $this->createContentVersion1();
2524
2525
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
2526
2527
        // Will return the VersionInfo of the $draftContent
2528
        $versionInfo = $contentService->loadVersionInfoById($publishedContent->id, 2);
2529
        /* END: Use Case */
2530
2531
        $this->assertEquals(2, $versionInfo->versionNo);
2532
2533
        // Check that ContentInfo contained in VersionInfo has correct main Location id set
2534
        $this->assertEquals(
2535
            $publishedContent->getVersionInfo()->getContentInfo()->mainLocationId,
2536
            $versionInfo->getContentInfo()->mainLocationId
2537
        );
2538
2539
        return [
2540
            'versionInfo' => $versionInfo,
2541
            'draftContent' => $draftContent,
2542
        ];
2543
    }
2544
2545
    /**
2546
     * Test for the returned value of the loadVersionInfoById() method.
2547
     *
2548
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoByIdWithSecondParameter
2549
     * @covers \eZ\Publish\API\Repository\ContentService::loadVersionInfoById
2550
     *
2551
     * @param array $data
2552
     */
2553
    public function testLoadVersionInfoByIdWithSecondParameterSetsExpectedVersionInfo(array $data)
2554
    {
2555
        /** @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo */
2556
        $versionInfo = $data['versionInfo'];
2557
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $draftContent */
2558
        $draftContent = $data['draftContent'];
2559
2560
        $this->assertPropertiesCorrect(
2561
            [
2562
                'names' => [
2563
                    'eng-US' => 'An awesome forum',
2564
                ],
2565
                'contentInfo' => new ContentInfo([
2566
                    'id' => $draftContent->contentInfo->id,
2567
                    'contentTypeId' => 28,
2568
                    'name' => 'An awesome forum',
2569
                    'sectionId' => 1,
2570
                    'currentVersionNo' => 1,
2571
                    'published' => true,
2572
                    'ownerId' => 14,
2573
                    // this Content Object is created at the test runtime
2574
                    'modificationDate' => $versionInfo->contentInfo->modificationDate,
2575
                    'publishedDate' => $versionInfo->contentInfo->publishedDate,
2576
                    'alwaysAvailable' => 1,
2577
                    'remoteId' => 'abcdef0123456789abcdef0123456789',
2578
                    'mainLanguageCode' => 'eng-US',
2579
                    'mainLocationId' => $draftContent->contentInfo->mainLocationId,
2580
                    'status' => ContentInfo::STATUS_PUBLISHED,
2581
                ]),
2582
                'id' => $draftContent->versionInfo->id,
2583
                'versionNo' => 2,
2584
                'creatorId' => 14,
2585
                'status' => 0,
2586
                'initialLanguageCode' => 'eng-US',
2587
                'languageCodes' => [
2588
                    'eng-US',
2589
                ],
2590
            ],
2591
            $versionInfo
2592
        );
2593
    }
2594
2595
    /**
2596
     * Test for the loadVersionInfoById() method.
2597
     *
2598
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
2599
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2600
     */
2601 View Code Duplication
    public function testLoadVersionInfoByIdThrowsNotFoundExceptionWithSecondParameter()
2602
    {
2603
        $repository = $this->getRepository();
2604
2605
        $contentService = $repository->getContentService();
2606
2607
        /* BEGIN: Use Case */
2608
        $content = $this->createContentVersion1();
2609
2610
        // This call will fail with a "NotFoundException", because not versionNo
2611
        // 2 exists for this content object.
2612
        $contentService->loadVersionInfoById($content->id, 2);
2613
        /* END: Use Case */
2614
    }
2615
2616
    /**
2617
     * Test for the loadContentByVersionInfo() method.
2618
     *
2619
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo($versionInfo, $languages)
2620
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
2621
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByVersionInfo
2622
     */
2623
    public function testLoadContentByVersionInfoWithSecondParameter()
2624
    {
2625
        $repository = $this->getRepository();
2626
2627
        $sectionId = $this->generateId('section', 1);
2628
        /* BEGIN: Use Case */
2629
        $contentTypeService = $repository->getContentTypeService();
2630
2631
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
2632
2633
        $contentService = $repository->getContentService();
2634
2635
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
2636
2637
        $contentCreateStruct->setField('name', 'Sindelfingen forum²');
2638
2639
        $contentCreateStruct->setField('name', 'Sindelfingen forum²³', 'eng-GB');
2640
2641
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
2642
        // $sectionId contains the ID of section 1
2643
        $contentCreateStruct->sectionId = $sectionId;
2644
        $contentCreateStruct->alwaysAvailable = true;
2645
2646
        // Create a new content draft
2647
        $content = $contentService->createContent($contentCreateStruct);
2648
2649
        // Now publish this draft
2650
        $publishedContent = $contentService->publishVersion($content->getVersionInfo());
2651
2652
        // Will return a content instance with fields in "eng-US"
2653
        $reloadedContent = $contentService->loadContentByVersionInfo(
2654
            $publishedContent->getVersionInfo(),
2655
            [
2656
                'eng-GB',
2657
            ],
2658
            false
2659
        );
2660
        /* END: Use Case */
2661
2662
        $actual = [];
2663
        foreach ($reloadedContent->getFields() as $field) {
2664
            $actual[] = new Field(
2665
                [
2666
                    'id' => 0,
2667
                    'value' => ($field->value !== null ? true : null), // Actual value tested by FieldType integration tests
2668
                    'languageCode' => $field->languageCode,
2669
                    'fieldDefIdentifier' => $field->fieldDefIdentifier,
2670
                ]
2671
            );
2672
        }
2673
        usort(
2674
            $actual,
2675 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...
2676
                if (0 === ($return = strcasecmp($field1->fieldDefIdentifier, $field2->fieldDefIdentifier))) {
2677
                    return strcasecmp($field1->languageCode, $field2->languageCode);
2678
                }
2679
2680
                return $return;
2681
            }
2682
        );
2683
2684
        $expected = [
2685
            new Field(
2686
                [
2687
                    'id' => 0,
2688
                    'value' => true,
2689
                    'languageCode' => 'eng-GB',
2690
                    'fieldDefIdentifier' => 'description',
2691
                ]
2692
            ),
2693
            new Field(
2694
                [
2695
                    'id' => 0,
2696
                    'value' => true,
2697
                    'languageCode' => 'eng-GB',
2698
                    'fieldDefIdentifier' => 'name',
2699
                ]
2700
            ),
2701
        ];
2702
2703
        $this->assertEquals($expected, $actual);
2704
    }
2705
2706
    /**
2707
     * Test for the loadContentByContentInfo() method.
2708
     *
2709
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages)
2710
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
2711
     */
2712
    public function testLoadContentByContentInfoWithLanguageParameters()
2713
    {
2714
        $repository = $this->getRepository();
2715
2716
        $sectionId = $this->generateId('section', 1);
2717
        /* BEGIN: Use Case */
2718
        $contentTypeService = $repository->getContentTypeService();
2719
2720
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
2721
2722
        $contentService = $repository->getContentService();
2723
2724
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
2725
2726
        $contentCreateStruct->setField('name', 'Sindelfingen forum²');
2727
2728
        $contentCreateStruct->setField('name', 'Sindelfingen forum²³', 'eng-GB');
2729
2730
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
2731
        // $sectionId contains the ID of section 1
2732
        $contentCreateStruct->sectionId = $sectionId;
2733
        $contentCreateStruct->alwaysAvailable = true;
2734
2735
        // Create a new content draft
2736
        $content = $contentService->createContent($contentCreateStruct);
2737
2738
        // Now publish this draft
2739
        $publishedContent = $contentService->publishVersion($content->getVersionInfo());
2740
2741
        // Will return a content instance with fields in "eng-US"
2742
        $reloadedContent = $contentService->loadContentByContentInfo(
2743
            $publishedContent->contentInfo,
2744
            [
2745
                'eng-US',
2746
            ],
2747
            null,
2748
            false
2749
        );
2750
        /* END: Use Case */
2751
2752
        $actual = $this->normalizeFields($reloadedContent->getFields());
2753
2754
        $expected = [
2755
            new Field(
2756
                [
2757
                    'id' => 0,
2758
                    'value' => true,
2759
                    'languageCode' => 'eng-US',
2760
                    'fieldDefIdentifier' => 'description',
2761
                    'fieldTypeIdentifier' => 'ezrichtext',
2762
                ]
2763
            ),
2764
            new Field(
2765
                [
2766
                    'id' => 0,
2767
                    'value' => true,
2768
                    'languageCode' => 'eng-US',
2769
                    'fieldDefIdentifier' => 'name',
2770
                    'fieldTypeIdentifier' => 'ezstring',
2771
                ]
2772
            ),
2773
        ];
2774
2775
        $this->assertEquals($expected, $actual);
2776
2777
        // Will return a content instance with fields in "eng-GB" (versions prior to 6.0.0-beta9 returned "eng-US" also)
2778
        $reloadedContent = $contentService->loadContentByContentInfo(
2779
            $publishedContent->contentInfo,
2780
            [
2781
                'eng-GB',
2782
            ],
2783
            null,
2784
            true
2785
        );
2786
2787
        $actual = $this->normalizeFields($reloadedContent->getFields());
2788
2789
        $expected = [
2790
            new Field(
2791
                [
2792
                    'id' => 0,
2793
                    'value' => true,
2794
                    'languageCode' => 'eng-GB',
2795
                    'fieldDefIdentifier' => 'description',
2796
                    'fieldTypeIdentifier' => 'ezrichtext',
2797
                ]
2798
            ),
2799
            new Field(
2800
                [
2801
                    'id' => 0,
2802
                    'value' => true,
2803
                    'languageCode' => 'eng-GB',
2804
                    'fieldDefIdentifier' => 'name',
2805
                    'fieldTypeIdentifier' => 'ezstring',
2806
                ]
2807
            ),
2808
        ];
2809
2810
        $this->assertEquals($expected, $actual);
2811
2812
        // Will return a content instance with fields in main language "eng-US", as "fre-FR" does not exists
2813
        $reloadedContent = $contentService->loadContentByContentInfo(
2814
            $publishedContent->contentInfo,
2815
            [
2816
                'fre-FR',
2817
            ],
2818
            null,
2819
            true
2820
        );
2821
2822
        $actual = $this->normalizeFields($reloadedContent->getFields());
2823
2824
        $expected = [
2825
            new Field(
2826
                [
2827
                    'id' => 0,
2828
                    'value' => true,
2829
                    'languageCode' => 'eng-US',
2830
                    'fieldDefIdentifier' => 'description',
2831
                    'fieldTypeIdentifier' => 'ezrichtext',
2832
                ]
2833
            ),
2834
            new Field(
2835
                [
2836
                    'id' => 0,
2837
                    'value' => true,
2838
                    'languageCode' => 'eng-US',
2839
                    'fieldDefIdentifier' => 'name',
2840
                    'fieldTypeIdentifier' => 'ezstring',
2841
                ]
2842
            ),
2843
        ];
2844
2845
        $this->assertEquals($expected, $actual);
2846
    }
2847
2848
    /**
2849
     * Test for the loadContentByContentInfo() method.
2850
     *
2851
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
2852
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
2853
     */
2854 View Code Duplication
    public function testLoadContentByContentInfoWithVersionNumberParameter()
2855
    {
2856
        $repository = $this->getRepository();
2857
2858
        $contentService = $repository->getContentService();
2859
2860
        /* BEGIN: Use Case */
2861
        $publishedContent = $this->createContentVersion1();
2862
2863
        $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...
2864
2865
        // This content instance is identical to $draftContent
2866
        $draftContentReloaded = $contentService->loadContentByContentInfo(
2867
            $publishedContent->contentInfo,
2868
            null,
2869
            2
2870
        );
2871
        /* END: Use Case */
2872
2873
        $this->assertEquals(
2874
            2,
2875
            $draftContentReloaded->getVersionInfo()->versionNo
2876
        );
2877
2878
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
2879
        $this->assertEquals(
2880
            $publishedContent->versionInfo->contentInfo->mainLocationId,
2881
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
2882
        );
2883
    }
2884
2885
    /**
2886
     * Test for the loadContentByContentInfo() method.
2887
     *
2888
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
2889
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2890
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfoWithVersionNumberParameter
2891
     */
2892 View Code Duplication
    public function testLoadContentByContentInfoThrowsNotFoundExceptionWithVersionNumberParameter()
2893
    {
2894
        $repository = $this->getRepository();
2895
2896
        $contentService = $repository->getContentService();
2897
2898
        /* BEGIN: Use Case */
2899
        $content = $this->createContentVersion1();
2900
2901
        // This call will fail with a "NotFoundException", because no content
2902
        // with versionNo = 2 exists.
2903
        $contentService->loadContentByContentInfo($content->contentInfo, null, 2);
2904
        /* END: Use Case */
2905
    }
2906
2907
    /**
2908
     * Test for the loadContent() method.
2909
     *
2910
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages)
2911
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2912
     */
2913 View Code Duplication
    public function testLoadContentWithSecondParameter()
2914
    {
2915
        $repository = $this->getRepository();
2916
2917
        $contentService = $repository->getContentService();
2918
2919
        /* BEGIN: Use Case */
2920
        $draft = $this->createMultipleLanguageDraftVersion1();
2921
2922
        // This draft contains those fields localized with "eng-GB"
2923
        $draftLocalized = $contentService->loadContent($draft->id, ['eng-GB'], null, false);
2924
        /* END: Use Case */
2925
2926
        $this->assertLocaleFieldsEquals($draftLocalized->getFields(), 'eng-GB');
2927
2928
        return $draft;
2929
    }
2930
2931
    /**
2932
     * Test for the loadContent() method using undefined translation.
2933
     *
2934
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithSecondParameter
2935
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2936
     *
2937
     * @param \eZ\Publish\API\Repository\Values\Content\Content $contentDraft
2938
     */
2939
    public function testLoadContentWithSecondParameterThrowsNotFoundException(Content $contentDraft)
2940
    {
2941
        $repository = $this->getRepository();
2942
2943
        $contentService = $repository->getContentService();
2944
2945
        $contentService->loadContent($contentDraft->id, ['ger-DE'], null, false);
2946
    }
2947
2948
    /**
2949
     * Test for the loadContent() method.
2950
     *
2951
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
2952
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2953
     */
2954 View Code Duplication
    public function testLoadContentWithThirdParameter()
2955
    {
2956
        $repository = $this->getRepository();
2957
2958
        $contentService = $repository->getContentService();
2959
2960
        /* BEGIN: Use Case */
2961
        $publishedContent = $this->createContentVersion1();
2962
2963
        $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...
2964
2965
        // This content instance is identical to $draftContent
2966
        $draftContentReloaded = $contentService->loadContent($publishedContent->id, null, 2);
2967
        /* END: Use Case */
2968
2969
        $this->assertEquals(2, $draftContentReloaded->getVersionInfo()->versionNo);
2970
2971
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
2972
        $this->assertEquals(
2973
            $publishedContent->versionInfo->contentInfo->mainLocationId,
2974
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
2975
        );
2976
    }
2977
2978
    /**
2979
     * Test for the loadContent() method.
2980
     *
2981
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
2982
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2983
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithThirdParameter
2984
     */
2985 View Code Duplication
    public function testLoadContentThrowsNotFoundExceptionWithThirdParameter()
2986
    {
2987
        $repository = $this->getRepository();
2988
2989
        $contentService = $repository->getContentService();
2990
2991
        /* BEGIN: Use Case */
2992
        $content = $this->createContentVersion1();
2993
2994
        // This call will fail with a "NotFoundException", because for this
2995
        // content object no versionNo=2 exists.
2996
        $contentService->loadContent($content->id, null, 2);
2997
        /* END: Use Case */
2998
    }
2999
3000
    /**
3001
     * Test for the loadContentByRemoteId() method.
3002
     *
3003
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages)
3004
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3005
     */
3006 View Code Duplication
    public function testLoadContentByRemoteIdWithSecondParameter()
3007
    {
3008
        $repository = $this->getRepository();
3009
3010
        $contentService = $repository->getContentService();
3011
3012
        /* BEGIN: Use Case */
3013
        $draft = $this->createMultipleLanguageDraftVersion1();
3014
3015
        $contentService->publishVersion($draft->versionInfo);
3016
3017
        // This draft contains those fields localized with "eng-GB"
3018
        $draftLocalized = $contentService->loadContentByRemoteId(
3019
            $draft->contentInfo->remoteId,
3020
            ['eng-GB'],
3021
            null,
3022
            false
3023
        );
3024
        /* END: Use Case */
3025
3026
        $this->assertLocaleFieldsEquals($draftLocalized->getFields(), 'eng-GB');
3027
    }
3028
3029
    /**
3030
     * Test for the loadContentByRemoteId() method.
3031
     *
3032
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
3033
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3034
     */
3035 View Code Duplication
    public function testLoadContentByRemoteIdWithThirdParameter()
3036
    {
3037
        $repository = $this->getRepository();
3038
3039
        $contentService = $repository->getContentService();
3040
3041
        /* BEGIN: Use Case */
3042
        $publishedContent = $this->createContentVersion1();
3043
3044
        $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...
3045
3046
        // This content instance is identical to $draftContent
3047
        $draftContentReloaded = $contentService->loadContentByRemoteId(
3048
            $publishedContent->contentInfo->remoteId,
3049
            null,
3050
            2
3051
        );
3052
        /* END: Use Case */
3053
3054
        $this->assertEquals(2, $draftContentReloaded->getVersionInfo()->versionNo);
3055
3056
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
3057
        $this->assertEquals(
3058
            $publishedContent->versionInfo->contentInfo->mainLocationId,
3059
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
3060
        );
3061
    }
3062
3063
    /**
3064
     * Test for the loadContentByRemoteId() method.
3065
     *
3066
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
3067
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
3068
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteIdWithThirdParameter
3069
     */
3070
    public function testLoadContentByRemoteIdThrowsNotFoundExceptionWithThirdParameter()
3071
    {
3072
        $repository = $this->getRepository();
3073
3074
        $contentService = $repository->getContentService();
3075
3076
        /* BEGIN: Use Case */
3077
        $content = $this->createContentVersion1();
3078
3079
        // This call will fail with a "NotFoundException", because for this
3080
        // content object no versionNo=2 exists.
3081
        $contentService->loadContentByRemoteId(
3082
            $content->contentInfo->remoteId,
3083
            null,
3084
            2
3085
        );
3086
        /* END: Use Case */
3087
    }
3088
3089
    /**
3090
     * Test that retrieval of translated name field respects prioritized language list.
3091
     *
3092
     * @dataProvider getPrioritizedLanguageList
3093
     * @param string[]|null $languageCodes
3094
     */
3095
    public function testLoadContentWithPrioritizedLanguagesList($languageCodes)
3096
    {
3097
        $repository = $this->getRepository();
3098
3099
        $contentService = $repository->getContentService();
3100
3101
        $content = $this->createContentVersion2();
3102
3103
        $content = $contentService->loadContent($content->id, $languageCodes);
3104
3105
        $expectedName = $content->getVersionInfo()->getName(
3106
            isset($languageCodes[0]) ? $languageCodes[0] : null
3107
        );
3108
        $nameValue = $content->getFieldValue('name');
3109
        /** @var \eZ\Publish\Core\FieldType\TextLine\Value $nameValue */
3110
        self::assertEquals($expectedName, $nameValue->text);
3111
        self::assertEquals($expectedName, $content->getVersionInfo()->getName());
3112
        // Also check value on shortcut method on content
3113
        self::assertEquals($expectedName, $content->getName());
3114
    }
3115
3116
    /**
3117
     * @return array
3118
     */
3119
    public function getPrioritizedLanguageList()
3120
    {
3121
        return [
3122
            [['eng-US']],
3123
            [['eng-GB']],
3124
            [['eng-GB', 'eng-US']],
3125
            [['eng-US', 'eng-GB']],
3126
        ];
3127
    }
3128
3129
    /**
3130
     * Test for the deleteVersion() method.
3131
     *
3132
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3133
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3134
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3135
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3136
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
3137
     */
3138
    public function testDeleteVersion()
3139
    {
3140
        $repository = $this->getRepository();
3141
3142
        $contentService = $repository->getContentService();
3143
3144
        /* BEGIN: Use Case */
3145
        $content = $this->createContentVersion1();
3146
3147
        // Create new draft, because published or last version of the Content can't be deleted
3148
        $draft = $contentService->createContentDraft(
3149
            $content->getVersionInfo()->getContentInfo()
3150
        );
3151
3152
        // Delete the previously created draft
3153
        $contentService->deleteVersion($draft->getVersionInfo());
3154
        /* END: Use Case */
3155
3156
        $versions = $contentService->loadVersions($content->getVersionInfo()->getContentInfo());
3157
3158
        $this->assertCount(1, $versions);
3159
        $this->assertEquals(
3160
            $content->getVersionInfo()->id,
3161
            $versions[0]->id
3162
        );
3163
    }
3164
3165
    /**
3166
     * Test for the deleteVersion() method.
3167
     *
3168
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3169
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
3170
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3171
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3172
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3173
     */
3174
    public function testDeleteVersionThrowsBadStateExceptionOnPublishedVersion()
3175
    {
3176
        $repository = $this->getRepository();
3177
3178
        $contentService = $repository->getContentService();
3179
3180
        /* BEGIN: Use Case */
3181
        $content = $this->createContentVersion1();
3182
3183
        // This call will fail with a "BadStateException", because the content
3184
        // version is currently published.
3185
        $contentService->deleteVersion($content->getVersionInfo());
3186
        /* END: Use Case */
3187
    }
3188
3189
    /**
3190
     * Test for the deleteVersion() method.
3191
     *
3192
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3193
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
3194
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3195
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3196
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3197
     */
3198
    public function testDeleteVersionWorksIfOnlyVersionIsDraft()
3199
    {
3200
        $repository = $this->getRepository();
3201
3202
        $contentService = $repository->getContentService();
3203
3204
        /* BEGIN: Use Case */
3205
        $draft = $this->createContentDraftVersion1();
3206
3207
        $contentService->deleteVersion($draft->getVersionInfo());
3208
3209
        // This call will fail with a "NotFound", because we allow to delete content if remaining version is draft.
3210
        // Can normally only happen if there where always only a draft to begin with, simplifies UI edit API usage.
3211
        $contentService->loadContent($draft->id);
3212
        /* END: Use Case */
3213
    }
3214
3215
    /**
3216
     * Test for the loadVersions() method.
3217
     *
3218
     * @see \eZ\Publish\API\Repository\ContentService::loadVersions()
3219
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3220
     *
3221
     * @return \eZ\Publish\API\Repository\Values\Content\VersionInfo[]
3222
     */
3223
    public function testLoadVersions()
3224
    {
3225
        $repository = $this->getRepository();
3226
3227
        $contentService = $repository->getContentService();
3228
3229
        /* BEGIN: Use Case */
3230
        $contentVersion2 = $this->createContentVersion2();
3231
3232
        // Load versions of this ContentInfo instance
3233
        $versions = $contentService->loadVersions($contentVersion2->contentInfo);
3234
        /* END: Use Case */
3235
3236
        $expectedVersionsOrder = [
3237
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 1),
3238
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 2),
3239
        ];
3240
3241
        $this->assertEquals($expectedVersionsOrder, $versions);
3242
3243
        return $versions;
3244
    }
3245
3246
    /**
3247
     * Test for the loadVersions() method.
3248
     *
3249
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersions
3250
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersions
3251
     *
3252
     * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo[] $versions
3253
     */
3254
    public function testLoadVersionsSetsExpectedVersionInfo(array $versions)
3255
    {
3256
        $this->assertCount(2, $versions);
3257
3258
        $expectedVersions = [
3259
            [
3260
                'versionNo' => 1,
3261
                'creatorId' => 14,
3262
                'status' => VersionInfo::STATUS_ARCHIVED,
3263
                'initialLanguageCode' => 'eng-US',
3264
                'languageCodes' => ['eng-US'],
3265
            ],
3266
            [
3267
                'versionNo' => 2,
3268
                'creatorId' => 10,
3269
                'status' => VersionInfo::STATUS_PUBLISHED,
3270
                'initialLanguageCode' => 'eng-US',
3271
                'languageCodes' => ['eng-US', 'eng-GB'],
3272
            ],
3273
        ];
3274
3275
        $this->assertPropertiesCorrect($expectedVersions[0], $versions[0]);
3276
        $this->assertPropertiesCorrect($expectedVersions[1], $versions[1]);
3277
        $this->assertEquals(
3278
            $versions[0]->creationDate->getTimestamp(),
3279
            $versions[1]->creationDate->getTimestamp(),
3280
            'Creation time did not match within delta of 2 seconds',
3281
            2
3282
        );
3283
        $this->assertEquals(
3284
            $versions[0]->modificationDate->getTimestamp(),
3285
            $versions[1]->modificationDate->getTimestamp(),
3286
            'Creation time did not match within delta of 2 seconds',
3287
            2
3288
        );
3289
        $this->assertTrue($versions[0]->isArchived());
3290
        $this->assertFalse($versions[0]->isDraft());
3291
        $this->assertFalse($versions[0]->isPublished());
3292
3293
        $this->assertTrue($versions[1]->isPublished());
3294
        $this->assertFalse($versions[1]->isDraft());
3295
        $this->assertFalse($versions[1]->isArchived());
3296
    }
3297
3298
    /**
3299
     * Test for the copyContent() method.
3300
     *
3301
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
3302
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3303
     * @group field-type
3304
     */
3305 View Code Duplication
    public function testCopyContent()
3306
    {
3307
        $parentLocationId = $this->generateId('location', 56);
3308
3309
        $repository = $this->getRepository();
3310
3311
        $contentService = $repository->getContentService();
3312
        $locationService = $repository->getLocationService();
3313
3314
        /* BEGIN: Use Case */
3315
        $contentVersion2 = $this->createMultipleLanguageContentVersion2();
3316
3317
        // Configure new target location
3318
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3319
3320
        $targetLocationCreate->priority = 42;
3321
        $targetLocationCreate->hidden = true;
3322
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3323
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3324
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3325
3326
        // Copy content with all versions and drafts
3327
        $contentCopied = $contentService->copyContent(
3328
            $contentVersion2->contentInfo,
3329
            $targetLocationCreate
3330
        );
3331
        /* END: Use Case */
3332
3333
        $this->assertInstanceOf(
3334
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
3335
            $contentCopied
3336
        );
3337
3338
        $this->assertNotEquals(
3339
            $contentVersion2->contentInfo->remoteId,
3340
            $contentCopied->contentInfo->remoteId
3341
        );
3342
3343
        $this->assertNotEquals(
3344
            $contentVersion2->id,
3345
            $contentCopied->id
3346
        );
3347
3348
        $this->assertEquals(
3349
            2,
3350
            count($contentService->loadVersions($contentCopied->contentInfo))
3351
        );
3352
3353
        $this->assertEquals(2, $contentCopied->getVersionInfo()->versionNo);
3354
3355
        $this->assertAllFieldsEquals($contentCopied->getFields());
3356
3357
        $this->assertDefaultContentStates($contentCopied->contentInfo);
3358
3359
        $this->assertNotNull(
3360
            $contentCopied->contentInfo->mainLocationId,
3361
            'Expected main location to be set given we provided a LocationCreateStruct'
3362
        );
3363
    }
3364
3365
    /**
3366
     * Test for the copyContent() method with ezsettings.default.content.retain_owner_on_copy set to false
3367
     * See settings/test/integration_legacy.yml for service override.
3368
     *
3369
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
3370
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3371
     * @group field-type
3372
     */
3373
    public function testCopyContentWithNewOwner()
3374
    {
3375
        $parentLocationId = $this->generateId('location', 56);
3376
3377
        $repository = $this->getRepository();
3378
3379
        $contentService = $repository->getContentService();
3380
        $locationService = $repository->getLocationService();
3381
        $userService = $repository->getUserService();
3382
3383
        $newOwner = $this->createUser('new_owner', 'foo', 'bar');
3384
        /* BEGIN: Use Case */
3385
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $contentVersion2 */
3386
        $contentVersion2 = $this->createContentDraftVersion1(
3387
            $parentLocationId,
3388
            'forum',
3389
            'name',
3390
            $newOwner
3391
        );
3392
3393
        // Configure new target location
3394
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3395
3396
        $targetLocationCreate->priority = 42;
3397
        $targetLocationCreate->hidden = true;
3398
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3399
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3400
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3401
3402
        // Copy content with all versions and drafts
3403
        $contentCopied = $contentService->copyContent(
3404
            $contentVersion2->contentInfo,
3405
            $targetLocationCreate
3406
        );
3407
        /* END: Use Case */
3408
3409
        $this->assertEquals(
3410
            $newOwner->id,
3411
            $contentVersion2->contentInfo->ownerId
3412
        );
3413
        $this->assertEquals(
3414
            $userService->loadUserByLogin('admin')->getUserId(),
3415
            $contentCopied->contentInfo->ownerId
3416
        );
3417
    }
3418
3419
    /**
3420
     * Test for the copyContent() method.
3421
     *
3422
     * @see \eZ\Publish\API\Repository\ContentService::copyContent($contentInfo, $destinationLocationCreateStruct, $versionInfo)
3423
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
3424
     */
3425 View Code Duplication
    public function testCopyContentWithGivenVersion()
3426
    {
3427
        $parentLocationId = $this->generateId('location', 56);
3428
3429
        $repository = $this->getRepository();
3430
3431
        $contentService = $repository->getContentService();
3432
        $locationService = $repository->getLocationService();
3433
3434
        /* BEGIN: Use Case */
3435
        $contentVersion2 = $this->createContentVersion2();
3436
3437
        // Configure new target location
3438
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3439
3440
        $targetLocationCreate->priority = 42;
3441
        $targetLocationCreate->hidden = true;
3442
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3443
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3444
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3445
3446
        // Copy only the initial version
3447
        $contentCopied = $contentService->copyContent(
3448
            $contentVersion2->contentInfo,
3449
            $targetLocationCreate,
3450
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 1)
3451
        );
3452
        /* END: Use Case */
3453
3454
        $this->assertInstanceOf(
3455
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
3456
            $contentCopied
3457
        );
3458
3459
        $this->assertNotEquals(
3460
            $contentVersion2->contentInfo->remoteId,
3461
            $contentCopied->contentInfo->remoteId
3462
        );
3463
3464
        $this->assertNotEquals(
3465
            $contentVersion2->id,
3466
            $contentCopied->id
3467
        );
3468
3469
        $this->assertEquals(
3470
            1,
3471
            count($contentService->loadVersions($contentCopied->contentInfo))
3472
        );
3473
3474
        $this->assertEquals(1, $contentCopied->getVersionInfo()->versionNo);
3475
3476
        $this->assertNotNull(
3477
            $contentCopied->contentInfo->mainLocationId,
3478
            'Expected main location to be set given we provided a LocationCreateStruct'
3479
        );
3480
    }
3481
3482
    /**
3483
     * Test for the addRelation() method.
3484
     *
3485
     * @return \eZ\Publish\API\Repository\Values\Content\Content
3486
     *
3487
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3488
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3489
     */
3490
    public function testAddRelation()
3491
    {
3492
        $repository = $this->getRepository();
3493
3494
        $contentService = $repository->getContentService();
3495
3496
        /* BEGIN: Use Case */
3497
        // RemoteId of the "Media" content of an eZ Publish demo installation
3498
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3499
3500
        $draft = $this->createContentDraftVersion1();
3501
3502
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3503
3504
        // Create relation between new content object and "Media" page
3505
        $relation = $contentService->addRelation(
3506
            $draft->getVersionInfo(),
3507
            $media
3508
        );
3509
        /* END: Use Case */
3510
3511
        $this->assertInstanceOf(
3512
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Relation',
3513
            $relation
3514
        );
3515
3516
        return $contentService->loadRelations($draft->getVersionInfo());
3517
    }
3518
3519
    /**
3520
     * Test for the addRelation() method.
3521
     *
3522
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3523
     *
3524
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3525
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3526
     */
3527
    public function testAddRelationAddsRelationToContent($relations)
3528
    {
3529
        $this->assertEquals(
3530
            1,
3531
            count($relations)
3532
        );
3533
    }
3534
3535
    /**
3536
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3537
     */
3538
    protected function assertExpectedRelations($relations)
3539
    {
3540
        $this->assertEquals(
3541
            [
3542
                'type' => Relation::COMMON,
3543
                'sourceFieldDefinitionIdentifier' => null,
3544
                'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3545
                'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3546
            ],
3547
            [
3548
                'type' => $relations[0]->type,
3549
                'sourceFieldDefinitionIdentifier' => $relations[0]->sourceFieldDefinitionIdentifier,
3550
                'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3551
                'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3552
            ]
3553
        );
3554
    }
3555
3556
    /**
3557
     * Test for the addRelation() method.
3558
     *
3559
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3560
     *
3561
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3562
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3563
     */
3564
    public function testAddRelationSetsExpectedRelations($relations)
3565
    {
3566
        $this->assertExpectedRelations($relations);
3567
    }
3568
3569
    /**
3570
     * Test for the createContentDraft() method.
3571
     *
3572
     * @return \eZ\Publish\API\Repository\Values\Content\Relation[]
3573
     *
3574
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
3575
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelationSetsExpectedRelations
3576
     */
3577 View Code Duplication
    public function testCreateContentDraftWithRelations()
3578
    {
3579
        $repository = $this->getRepository();
3580
3581
        $contentService = $repository->getContentService();
3582
3583
        // RemoteId of the "Media" content of an eZ Publish demo installation
3584
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3585
        $draft = $this->createContentDraftVersion1();
3586
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3587
3588
        // Create relation between new content object and "Media" page
3589
        $contentService->addRelation(
3590
            $draft->getVersionInfo(),
3591
            $media
3592
        );
3593
3594
        $content = $contentService->publishVersion($draft->versionInfo);
3595
        $newDraft = $contentService->createContentDraft($content->contentInfo);
3596
3597
        return $contentService->loadRelations($newDraft->getVersionInfo());
3598
    }
3599
3600
    /**
3601
     * Test for the createContentDraft() method.
3602
     *
3603
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3604
     *
3605
     * @return \eZ\Publish\API\Repository\Values\Content\Relation[]
3606
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithRelations
3607
     */
3608
    public function testCreateContentDraftWithRelationsCreatesRelations($relations)
3609
    {
3610
        $this->assertEquals(
3611
            1,
3612
            count($relations)
3613
        );
3614
3615
        return $relations;
3616
    }
3617
3618
    /**
3619
     * Test for the createContentDraft() method.
3620
     *
3621
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3622
     *
3623
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithRelationsCreatesRelations
3624
     */
3625
    public function testCreateContentDraftWithRelationsCreatesExpectedRelations($relations)
3626
    {
3627
        $this->assertExpectedRelations($relations);
3628
    }
3629
3630
    /**
3631
     * Test for the addRelation() method.
3632
     *
3633
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3634
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
3635
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3636
     */
3637 View Code Duplication
    public function testAddRelationThrowsBadStateException()
3638
    {
3639
        $repository = $this->getRepository();
3640
3641
        $contentService = $repository->getContentService();
3642
3643
        /* BEGIN: Use Case */
3644
        // RemoteId of the "Media" page of an eZ Publish demo installation
3645
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3646
3647
        $content = $this->createContentVersion1();
3648
3649
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3650
3651
        // This call will fail with a "BadStateException", because content is
3652
        // published and not a draft.
3653
        $contentService->addRelation(
3654
            $content->getVersionInfo(),
3655
            $media
3656
        );
3657
        /* END: Use Case */
3658
    }
3659
3660
    /**
3661
     * Test for the loadRelations() method.
3662
     *
3663
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3664
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3665
     */
3666
    public function testLoadRelations()
3667
    {
3668
        $repository = $this->getRepository();
3669
3670
        $contentService = $repository->getContentService();
3671
3672
        /* BEGIN: Use Case */
3673
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3674
        // of a eZ Publish demo installation.
3675
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3676
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3677
3678
        $draft = $this->createContentDraftVersion1();
3679
3680
        // Load other content objects
3681
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3682
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3683
3684
        // Create relation between new content object and "Media" page
3685
        $contentService->addRelation(
3686
            $draft->getVersionInfo(),
3687
            $media
3688
        );
3689
3690
        // Create another relation with the "Demo Design" page
3691
        $contentService->addRelation(
3692
            $draft->getVersionInfo(),
3693
            $demoDesign
3694
        );
3695
3696
        // Load all relations
3697
        $relations = $contentService->loadRelations($draft->getVersionInfo());
3698
        /* END: Use Case */
3699
3700
        usort(
3701
            $relations,
3702
            function ($rel1, $rel2) {
3703
                return strcasecmp(
3704
                    $rel2->getDestinationContentInfo()->remoteId,
3705
                    $rel1->getDestinationContentInfo()->remoteId
3706
                );
3707
            }
3708
        );
3709
3710
        $this->assertEquals(
3711
            [
3712
                [
3713
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3714
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3715
                ],
3716
                [
3717
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3718
                    'destinationContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3719
                ],
3720
            ],
3721
            [
3722
                [
3723
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3724
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3725
                ],
3726
                [
3727
                    'sourceContentInfo' => $relations[1]->sourceContentInfo->remoteId,
3728
                    'destinationContentInfo' => $relations[1]->destinationContentInfo->remoteId,
3729
                ],
3730
            ]
3731
        );
3732
    }
3733
3734
    /**
3735
     * Test for the loadRelations() method.
3736
     *
3737
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3738
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3739
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
3740
     */
3741
    public function testLoadRelationsSkipsArchivedContent()
3742
    {
3743
        $repository = $this->getRepository();
3744
3745
        $contentService = $repository->getContentService();
3746
3747
        /* BEGIN: Use Case */
3748
        $trashService = $repository->getTrashService();
3749
        $locationService = $repository->getLocationService();
3750
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3751
        // of a eZ Publish demo installation.
3752
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3753
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3754
3755
        $draft = $this->createContentDraftVersion1();
3756
3757
        // Load other content objects
3758
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3759
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3760
3761
        // Create relation between new content object and "Media" page
3762
        $contentService->addRelation(
3763
            $draft->getVersionInfo(),
3764
            $media
3765
        );
3766
3767
        // Create another relation with the "Demo Design" page
3768
        $contentService->addRelation(
3769
            $draft->getVersionInfo(),
3770
            $demoDesign
3771
        );
3772
3773
        $demoDesignLocation = $locationService->loadLocation($demoDesign->mainLocationId);
3774
3775
        // Trashing Content's last Location will change its status to archived,
3776
        // in this case relation towards it will not be loaded.
3777
        $trashService->trash($demoDesignLocation);
3778
3779
        // Load all relations
3780
        $relations = $contentService->loadRelations($draft->getVersionInfo());
3781
        /* END: Use Case */
3782
3783
        $this->assertCount(1, $relations);
3784
        $this->assertEquals(
3785
            [
3786
                [
3787
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3788
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3789
                ],
3790
            ],
3791
            [
3792
                [
3793
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3794
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3795
                ],
3796
            ]
3797
        );
3798
    }
3799
3800
    /**
3801
     * Test for the loadRelations() method.
3802
     *
3803
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3804
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3805
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
3806
     */
3807
    public function testLoadRelationsSkipsDraftContent()
3808
    {
3809
        $repository = $this->getRepository();
3810
3811
        $contentService = $repository->getContentService();
3812
3813
        /* BEGIN: Use Case */
3814
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3815
        // of a eZ Publish demo installation.
3816
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3817
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3818
3819
        $draft = $this->createContentDraftVersion1();
3820
3821
        // Load other content objects
3822
        $media = $contentService->loadContentByRemoteId($mediaRemoteId);
3823
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3824
3825
        // Create draft of "Media" page
3826
        $mediaDraft = $contentService->createContentDraft($media->contentInfo);
3827
3828
        // Create relation between "Media" page and new content object draft.
3829
        // This relation will not be loaded before the draft is published.
3830
        $contentService->addRelation(
3831
            $mediaDraft->getVersionInfo(),
3832
            $draft->getVersionInfo()->getContentInfo()
3833
        );
3834
3835
        // Create another relation with the "Demo Design" page
3836
        $contentService->addRelation(
3837
            $mediaDraft->getVersionInfo(),
3838
            $demoDesign
3839
        );
3840
3841
        // Load all relations
3842
        $relations = $contentService->loadRelations($mediaDraft->getVersionInfo());
3843
        /* END: Use Case */
3844
3845
        $this->assertCount(1, $relations);
3846
        $this->assertEquals(
3847
            [
3848
                [
3849
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3850
                    'destinationContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3851
                ],
3852
            ],
3853
            [
3854
                [
3855
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3856
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3857
                ],
3858
            ]
3859
        );
3860
    }
3861
3862
    /**
3863
     * Test for the loadReverseRelations() method.
3864
     *
3865
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
3866
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3867
     */
3868
    public function testLoadReverseRelations()
3869
    {
3870
        $repository = $this->getRepository();
3871
3872
        $contentService = $repository->getContentService();
3873
3874
        /* BEGIN: Use Case */
3875
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3876
        // of a eZ Publish demo installation.
3877
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3878
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3879
3880
        $versionInfo = $this->createContentVersion1()->getVersionInfo();
3881
        $contentInfo = $versionInfo->getContentInfo();
3882
3883
        // Create some drafts
3884
        $mediaDraft = $contentService->createContentDraft(
3885
            $contentService->loadContentInfoByRemoteId($mediaRemoteId)
3886
        );
3887
        $demoDesignDraft = $contentService->createContentDraft(
3888
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
3889
        );
3890
3891
        // Create relation between new content object and "Media" page
3892
        $relation1 = $contentService->addRelation(
3893
            $mediaDraft->getVersionInfo(),
3894
            $contentInfo
3895
        );
3896
3897
        // Create another relation with the "Demo Design" page
3898
        $relation2 = $contentService->addRelation(
3899
            $demoDesignDraft->getVersionInfo(),
3900
            $contentInfo
3901
        );
3902
3903
        // Publish drafts, so relations become active
3904
        $contentService->publishVersion($mediaDraft->getVersionInfo());
3905
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
3906
3907
        // Load all relations
3908
        $relations = $contentService->loadRelations($versionInfo);
3909
        $reverseRelations = $contentService->loadReverseRelations($contentInfo);
3910
        /* END: Use Case */
3911
3912
        $this->assertEquals($contentInfo->id, $relation1->getDestinationContentInfo()->id);
3913
        $this->assertEquals($mediaDraft->id, $relation1->getSourceContentInfo()->id);
3914
3915
        $this->assertEquals($contentInfo->id, $relation2->getDestinationContentInfo()->id);
3916
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
3917
3918
        $this->assertEquals(0, count($relations));
3919
        $this->assertEquals(2, count($reverseRelations));
3920
3921
        usort(
3922
            $reverseRelations,
3923
            function ($rel1, $rel2) {
3924
                return strcasecmp(
3925
                    $rel2->getSourceContentInfo()->remoteId,
3926
                    $rel1->getSourceContentInfo()->remoteId
3927
                );
3928
            }
3929
        );
3930
3931
        $this->assertEquals(
3932
            [
3933
                [
3934
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3935
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
3936
                ],
3937
                [
3938
                    'sourceContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3939
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
3940
                ],
3941
            ],
3942
            [
3943
                [
3944
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
3945
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
3946
                ],
3947
                [
3948
                    'sourceContentInfo' => $reverseRelations[1]->sourceContentInfo->remoteId,
3949
                    'destinationContentInfo' => $reverseRelations[1]->destinationContentInfo->remoteId,
3950
                ],
3951
            ]
3952
        );
3953
    }
3954
3955
    /**
3956
     * Test for the loadReverseRelations() method.
3957
     *
3958
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
3959
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3960
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
3961
     */
3962
    public function testLoadReverseRelationsSkipsArchivedContent()
3963
    {
3964
        $repository = $this->getRepository();
3965
3966
        $contentService = $repository->getContentService();
3967
3968
        /* BEGIN: Use Case */
3969
        $trashService = $repository->getTrashService();
3970
        $locationService = $repository->getLocationService();
3971
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3972
        // of a eZ Publish demo installation.
3973
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3974
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3975
3976
        $versionInfo = $this->createContentVersion1()->getVersionInfo();
3977
        $contentInfo = $versionInfo->getContentInfo();
3978
3979
        // Create some drafts
3980
        $mediaDraft = $contentService->createContentDraft(
3981
            $contentService->loadContentInfoByRemoteId($mediaRemoteId)
3982
        );
3983
        $demoDesignDraft = $contentService->createContentDraft(
3984
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
3985
        );
3986
3987
        // Create relation between new content object and "Media" page
3988
        $relation1 = $contentService->addRelation(
3989
            $mediaDraft->getVersionInfo(),
3990
            $contentInfo
3991
        );
3992
3993
        // Create another relation with the "Demo Design" page
3994
        $relation2 = $contentService->addRelation(
3995
            $demoDesignDraft->getVersionInfo(),
3996
            $contentInfo
3997
        );
3998
3999
        // Publish drafts, so relations become active
4000
        $contentService->publishVersion($mediaDraft->getVersionInfo());
4001
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
4002
4003
        $demoDesignLocation = $locationService->loadLocation($demoDesignDraft->contentInfo->mainLocationId);
4004
4005
        // Trashing Content's last Location will change its status to archived,
4006
        // in this case relation from it will not be loaded.
4007
        $trashService->trash($demoDesignLocation);
4008
4009
        // Load all relations
4010
        $relations = $contentService->loadRelations($versionInfo);
4011
        $reverseRelations = $contentService->loadReverseRelations($contentInfo);
4012
        /* END: Use Case */
4013
4014
        $this->assertEquals($contentInfo->id, $relation1->getDestinationContentInfo()->id);
4015
        $this->assertEquals($mediaDraft->id, $relation1->getSourceContentInfo()->id);
4016
4017
        $this->assertEquals($contentInfo->id, $relation2->getDestinationContentInfo()->id);
4018
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
4019
4020
        $this->assertEquals(0, count($relations));
4021
        $this->assertEquals(1, count($reverseRelations));
4022
4023
        $this->assertEquals(
4024
            [
4025
                [
4026
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
4027
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
4028
                ],
4029
            ],
4030
            [
4031
                [
4032
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
4033
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
4034
                ],
4035
            ]
4036
        );
4037
    }
4038
4039
    /**
4040
     * Test for the loadReverseRelations() method.
4041
     *
4042
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
4043
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
4044
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
4045
     */
4046
    public function testLoadReverseRelationsSkipsDraftContent()
4047
    {
4048
        $repository = $this->getRepository();
4049
4050
        $contentService = $repository->getContentService();
4051
4052
        /* BEGIN: Use Case */
4053
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
4054
        // of a eZ Publish demo installation.
4055
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4056
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
4057
4058
        // Load "Media" page Content
4059
        $media = $contentService->loadContentByRemoteId($mediaRemoteId);
4060
4061
        // Create some drafts
4062
        $newDraftVersionInfo = $this->createContentDraftVersion1()->getVersionInfo();
4063
        $demoDesignDraft = $contentService->createContentDraft(
4064
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
4065
        );
4066
4067
        // Create relation between "Media" page and new content object
4068
        $relation1 = $contentService->addRelation(
4069
            $newDraftVersionInfo,
4070
            $media->contentInfo
4071
        );
4072
4073
        // Create another relation with the "Demo Design" page
4074
        $relation2 = $contentService->addRelation(
4075
            $demoDesignDraft->getVersionInfo(),
4076
            $media->contentInfo
4077
        );
4078
4079
        // Publish drafts, so relations become active
4080
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
4081
        // We will not publish new Content draft, therefore relation from it
4082
        // will not be loaded as reverse relation for "Media" page
4083
        //$contentService->publishVersion( $newDraftVersionInfo );
4084
4085
        // Load all relations
4086
        $relations = $contentService->loadRelations($media->versionInfo);
4087
        $reverseRelations = $contentService->loadReverseRelations($media->contentInfo);
4088
        /* END: Use Case */
4089
4090
        $this->assertEquals($media->contentInfo->id, $relation1->getDestinationContentInfo()->id);
4091
        $this->assertEquals($newDraftVersionInfo->contentInfo->id, $relation1->getSourceContentInfo()->id);
4092
4093
        $this->assertEquals($media->contentInfo->id, $relation2->getDestinationContentInfo()->id);
4094
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
4095
4096
        $this->assertEquals(0, count($relations));
4097
        $this->assertEquals(1, count($reverseRelations));
4098
4099
        $this->assertEquals(
4100
            [
4101
                [
4102
                    'sourceContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
4103
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
4104
                ],
4105
            ],
4106
            [
4107
                [
4108
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
4109
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
4110
                ],
4111
            ]
4112
        );
4113
    }
4114
4115
    /**
4116
     * Test for the deleteRelation() method.
4117
     *
4118
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4119
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
4120
     */
4121
    public function testDeleteRelation()
4122
    {
4123
        $repository = $this->getRepository();
4124
4125
        $contentService = $repository->getContentService();
4126
4127
        /* BEGIN: Use Case */
4128
        // Remote ids of the "Media" and the "Demo Design" page of a eZ Publish
4129
        // demo installation.
4130
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4131
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
4132
4133
        $draft = $this->createContentDraftVersion1();
4134
4135
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4136
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
4137
4138
        // Establish some relations
4139
        $contentService->addRelation($draft->getVersionInfo(), $media);
4140
        $contentService->addRelation($draft->getVersionInfo(), $demoDesign);
4141
4142
        // Delete one of the currently created relations
4143
        $contentService->deleteRelation($draft->getVersionInfo(), $media);
4144
4145
        // The relations array now contains only one element
4146
        $relations = $contentService->loadRelations($draft->getVersionInfo());
4147
        /* END: Use Case */
4148
4149
        $this->assertEquals(1, count($relations));
4150
    }
4151
4152
    /**
4153
     * Test for the deleteRelation() method.
4154
     *
4155
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4156
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
4157
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
4158
     */
4159 View Code Duplication
    public function testDeleteRelationThrowsBadStateException()
4160
    {
4161
        $repository = $this->getRepository();
4162
4163
        $contentService = $repository->getContentService();
4164
4165
        /* BEGIN: Use Case */
4166
        // RemoteId of the "Media" page of an eZ Publish demo installation
4167
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4168
4169
        $content = $this->createContentVersion1();
4170
4171
        // Load the destination object
4172
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4173
4174
        // Create a new draft
4175
        $draftVersion2 = $contentService->createContentDraft($content->contentInfo);
4176
4177
        // Add a relation
4178
        $contentService->addRelation($draftVersion2->getVersionInfo(), $media);
4179
4180
        // Publish new version
4181
        $contentVersion2 = $contentService->publishVersion(
4182
            $draftVersion2->getVersionInfo()
4183
        );
4184
4185
        // This call will fail with a "BadStateException", because content is
4186
        // published and not a draft.
4187
        $contentService->deleteRelation(
4188
            $contentVersion2->getVersionInfo(),
4189
            $media
4190
        );
4191
        /* END: Use Case */
4192
    }
4193
4194
    /**
4195
     * Test for the deleteRelation() method.
4196
     *
4197
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4198
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
4199
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
4200
     */
4201 View Code Duplication
    public function testDeleteRelationThrowsInvalidArgumentException()
4202
    {
4203
        $repository = $this->getRepository();
4204
4205
        $contentService = $repository->getContentService();
4206
4207
        /* BEGIN: Use Case */
4208
        // RemoteId of the "Media" page of an eZ Publish demo installation
4209
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4210
4211
        $draft = $this->createContentDraftVersion1();
4212
4213
        // Load the destination object
4214
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4215
4216
        // This call will fail with a "InvalidArgumentException", because no
4217
        // relation exists between $draft and $media.
4218
        $contentService->deleteRelation(
4219
            $draft->getVersionInfo(),
4220
            $media
4221
        );
4222
        /* END: Use Case */
4223
    }
4224
4225
    /**
4226
     * Test for the createContent() method.
4227
     *
4228
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
4229
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4230
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4231
     */
4232
    public function testCreateContentInTransactionWithRollback()
4233
    {
4234
        if ($this->isVersion4()) {
4235
            $this->markTestSkipped('This test requires eZ Publish 5');
4236
        }
4237
4238
        $repository = $this->getRepository();
4239
4240
        /* BEGIN: Use Case */
4241
        $contentTypeService = $repository->getContentTypeService();
4242
        $contentService = $repository->getContentService();
4243
4244
        // Start a transaction
4245
        $repository->beginTransaction();
4246
4247
        try {
4248
            $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
4249
4250
            // Get a content create struct and set mandatory properties
4251
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
4252
            $contentCreate->setField('name', 'Sindelfingen forum');
4253
4254
            $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
4255
            $contentCreate->alwaysAvailable = true;
4256
4257
            // Create a new content object
4258
            $contentId = $contentService->createContent($contentCreate)->id;
4259
        } catch (Exception $e) {
4260
            // Cleanup hanging transaction on error
4261
            $repository->rollback();
4262
            throw $e;
4263
        }
4264
4265
        // Rollback all changes
4266
        $repository->rollback();
4267
4268
        try {
4269
            // This call will fail with a "NotFoundException"
4270
            $contentService->loadContent($contentId);
4271
        } catch (NotFoundException $e) {
4272
            // This is expected
4273
            return;
4274
        }
4275
        /* END: Use Case */
4276
4277
        $this->fail('Content object still exists after rollback.');
4278
    }
4279
4280
    /**
4281
     * Test for the createContent() method.
4282
     *
4283
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
4284
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4285
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4286
     */
4287
    public function testCreateContentInTransactionWithCommit()
4288
    {
4289
        if ($this->isVersion4()) {
4290
            $this->markTestSkipped('This test requires eZ Publish 5');
4291
        }
4292
4293
        $repository = $this->getRepository();
4294
4295
        /* BEGIN: Use Case */
4296
        $contentTypeService = $repository->getContentTypeService();
4297
        $contentService = $repository->getContentService();
4298
4299
        // Start a transaction
4300
        $repository->beginTransaction();
4301
4302
        try {
4303
            $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
4304
4305
            // Get a content create struct and set mandatory properties
4306
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
4307
            $contentCreate->setField('name', 'Sindelfingen forum');
4308
4309
            $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
4310
            $contentCreate->alwaysAvailable = true;
4311
4312
            // Create a new content object
4313
            $contentId = $contentService->createContent($contentCreate)->id;
4314
4315
            // Commit changes
4316
            $repository->commit();
4317
        } catch (Exception $e) {
4318
            // Cleanup hanging transaction on error
4319
            $repository->rollback();
4320
            throw $e;
4321
        }
4322
4323
        // Load the new content object
4324
        $content = $contentService->loadContent($contentId);
4325
        /* END: Use Case */
4326
4327
        $this->assertEquals($contentId, $content->id);
4328
    }
4329
4330
    /**
4331
     * Test for the createContent() method.
4332
     *
4333
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
4334
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
4335
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentThrowsNotFoundException
4336
     */
4337 View Code Duplication
    public function testCreateContentWithLocationCreateParameterInTransactionWithRollback()
4338
    {
4339
        $repository = $this->getRepository();
4340
4341
        $contentService = $repository->getContentService();
4342
4343
        /* BEGIN: Use Case */
4344
        // Start a transaction
4345
        $repository->beginTransaction();
4346
4347
        try {
4348
            $draft = $this->createContentDraftVersion1();
4349
        } catch (Exception $e) {
4350
            // Cleanup hanging transaction on error
4351
            $repository->rollback();
4352
            throw $e;
4353
        }
4354
4355
        $contentId = $draft->id;
4356
4357
        // Roleback the transaction
4358
        $repository->rollback();
4359
4360
        try {
4361
            // This call will fail with a "NotFoundException"
4362
            $contentService->loadContent($contentId);
4363
        } catch (NotFoundException $e) {
4364
            return;
4365
        }
4366
        /* END: Use Case */
4367
4368
        $this->fail('Can still load content object after rollback.');
4369
    }
4370
4371
    /**
4372
     * Test for the createContent() method.
4373
     *
4374
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
4375
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
4376
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentThrowsNotFoundException
4377
     */
4378 View Code Duplication
    public function testCreateContentWithLocationCreateParameterInTransactionWithCommit()
4379
    {
4380
        $repository = $this->getRepository();
4381
4382
        $contentService = $repository->getContentService();
4383
4384
        /* BEGIN: Use Case */
4385
        // Start a transaction
4386
        $repository->beginTransaction();
4387
4388
        try {
4389
            $draft = $this->createContentDraftVersion1();
4390
4391
            $contentId = $draft->id;
4392
4393
            // Roleback the transaction
4394
            $repository->commit();
4395
        } catch (Exception $e) {
4396
            // Cleanup hanging transaction on error
4397
            $repository->rollback();
4398
            throw $e;
4399
        }
4400
4401
        // Load the new content object
4402
        $content = $contentService->loadContent($contentId);
4403
        /* END: Use Case */
4404
4405
        $this->assertEquals($contentId, $content->id);
4406
    }
4407
4408
    /**
4409
     * Test for the createContentDraft() method.
4410
     *
4411
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
4412
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
4413
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4414
     */
4415
    public function testCreateContentDraftInTransactionWithRollback()
4416
    {
4417
        $repository = $this->getRepository();
4418
4419
        $contentId = $this->generateId('object', 12);
4420
        /* BEGIN: Use Case */
4421
        // $contentId is the ID of the "Administrator users" user group
4422
4423
        // Get the content service
4424
        $contentService = $repository->getContentService();
4425
4426
        // Load the user group content object
4427
        $content = $contentService->loadContent($contentId);
4428
4429
        // Start a new transaction
4430
        $repository->beginTransaction();
4431
4432
        try {
4433
            // Create a new draft
4434
            $drafted = $contentService->createContentDraft($content->contentInfo);
4435
4436
            // Store version number for later reuse
4437
            $versionNo = $drafted->versionInfo->versionNo;
4438
        } catch (Exception $e) {
4439
            // Cleanup hanging transaction on error
4440
            $repository->rollback();
4441
            throw $e;
4442
        }
4443
4444
        // Rollback
4445
        $repository->rollback();
4446
4447
        try {
4448
            // This call will fail with a "NotFoundException"
4449
            $contentService->loadContent($contentId, null, $versionNo);
4450
        } catch (NotFoundException $e) {
4451
            return;
4452
        }
4453
        /* END: Use Case */
4454
4455
        $this->fail('Can still load content draft after rollback');
4456
    }
4457
4458
    /**
4459
     * Test for the createContentDraft() method.
4460
     *
4461
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
4462
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
4463
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4464
     */
4465 View Code Duplication
    public function testCreateContentDraftInTransactionWithCommit()
4466
    {
4467
        $repository = $this->getRepository();
4468
4469
        $contentId = $this->generateId('object', 12);
4470
        /* BEGIN: Use Case */
4471
        // $contentId is the ID of the "Administrator users" user group
4472
4473
        // Get the content service
4474
        $contentService = $repository->getContentService();
4475
4476
        // Load the user group content object
4477
        $content = $contentService->loadContent($contentId);
4478
4479
        // Start a new transaction
4480
        $repository->beginTransaction();
4481
4482
        try {
4483
            // Create a new draft
4484
            $drafted = $contentService->createContentDraft($content->contentInfo);
4485
4486
            // Store version number for later reuse
4487
            $versionNo = $drafted->versionInfo->versionNo;
4488
4489
            // Commit all changes
4490
            $repository->commit();
4491
        } catch (Exception $e) {
4492
            // Cleanup hanging transaction on error
4493
            $repository->rollback();
4494
            throw $e;
4495
        }
4496
4497
        $content = $contentService->loadContent($contentId, null, $versionNo);
4498
        /* END: Use Case */
4499
4500
        $this->assertEquals(
4501
            $versionNo,
4502
            $content->getVersionInfo()->versionNo
4503
        );
4504
    }
4505
4506
    /**
4507
     * Test for the publishVersion() method.
4508
     *
4509
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
4510
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
4511
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4512
     */
4513 View Code Duplication
    public function testPublishVersionInTransactionWithRollback()
4514
    {
4515
        $repository = $this->getRepository();
4516
4517
        $contentId = $this->generateId('object', 12);
4518
        /* BEGIN: Use Case */
4519
        // $contentId is the ID of the "Administrator users" user group
4520
4521
        // Get the content service
4522
        $contentService = $repository->getContentService();
4523
4524
        // Load the user group content object
4525
        $content = $contentService->loadContent($contentId);
4526
4527
        // Start a new transaction
4528
        $repository->beginTransaction();
4529
4530
        try {
4531
            $draftVersion = $contentService->createContentDraft($content->contentInfo)->getVersionInfo();
4532
4533
            // Publish a new version
4534
            $content = $contentService->publishVersion($draftVersion);
4535
4536
            // Store version number for later reuse
4537
            $versionNo = $content->versionInfo->versionNo;
4538
        } catch (Exception $e) {
4539
            // Cleanup hanging transaction on error
4540
            $repository->rollback();
4541
            throw $e;
4542
        }
4543
4544
        // Rollback
4545
        $repository->rollback();
4546
4547
        try {
4548
            // This call will fail with a "NotFoundException"
4549
            $contentService->loadContent($contentId, null, $versionNo);
4550
        } catch (NotFoundException $e) {
4551
            return;
4552
        }
4553
        /* END: Use Case */
4554
4555
        $this->fail('Can still load content draft after rollback');
4556
    }
4557
4558
    /**
4559
     * Test for the publishVersion() method.
4560
     *
4561
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
4562
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
4563
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
4564
     */
4565 View Code Duplication
    public function testPublishVersionInTransactionWithCommit()
4566
    {
4567
        $repository = $this->getRepository();
4568
4569
        /* BEGIN: Use Case */
4570
        // ID of the "Administrator users" user group
4571
        $contentId = 12;
4572
4573
        // Get the content service
4574
        $contentService = $repository->getContentService();
4575
4576
        // Load the user group content object
4577
        $template = $contentService->loadContent($contentId);
4578
4579
        // Start a new transaction
4580
        $repository->beginTransaction();
4581
4582
        try {
4583
            // Publish a new version
4584
            $content = $contentService->publishVersion(
4585
                $contentService->createContentDraft($template->contentInfo)->getVersionInfo()
4586
            );
4587
4588
            // Store version number for later reuse
4589
            $versionNo = $content->versionInfo->versionNo;
4590
4591
            // Commit all changes
4592
            $repository->commit();
4593
        } catch (Exception $e) {
4594
            // Cleanup hanging transaction on error
4595
            $repository->rollback();
4596
            throw $e;
4597
        }
4598
4599
        // Load current version info
4600
        $versionInfo = $contentService->loadVersionInfo($content->contentInfo);
4601
        /* END: Use Case */
4602
4603
        $this->assertEquals($versionNo, $versionInfo->versionNo);
4604
    }
4605
4606
    /**
4607
     * Test for the updateContent() method.
4608
     *
4609
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
4610
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
4611
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4612
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4613
     */
4614 View Code Duplication
    public function testUpdateContentInTransactionWithRollback()
4615
    {
4616
        $repository = $this->getRepository();
4617
4618
        $contentId = $this->generateId('object', 12);
4619
        /* BEGIN: Use Case */
4620
        // $contentId is the ID of the "Administrator users" user group
4621
4622
        // Load content service
4623
        $contentService = $repository->getContentService();
4624
4625
        // Create a new user group draft
4626
        $draft = $contentService->createContentDraft(
4627
            $contentService->loadContentInfo($contentId)
4628
        );
4629
4630
        // Get an update struct and change the group name
4631
        $contentUpdate = $contentService->newContentUpdateStruct();
4632
        $contentUpdate->setField('name', 'Administrators', 'eng-US');
4633
4634
        // Start a transaction
4635
        $repository->beginTransaction();
4636
4637
        try {
4638
            // Update the group name
4639
            $draft = $contentService->updateContent(
4640
                $draft->getVersionInfo(),
4641
                $contentUpdate
4642
            );
4643
4644
            // Publish updated version
4645
            $contentService->publishVersion($draft->getVersionInfo());
4646
        } catch (Exception $e) {
4647
            // Cleanup hanging transaction on error
4648
            $repository->rollback();
4649
            throw $e;
4650
        }
4651
4652
        // Rollback all changes.
4653
        $repository->rollback();
4654
4655
        // Name will still be "Administrator users"
4656
        $name = $contentService->loadContent($contentId)->getFieldValue('name');
4657
        /* END: Use Case */
4658
4659
        $this->assertEquals('Administrator users', $name);
4660
    }
4661
4662
    /**
4663
     * Test for the updateContent() method.
4664
     *
4665
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
4666
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
4667
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4668
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4669
     */
4670 View Code Duplication
    public function testUpdateContentInTransactionWithCommit()
4671
    {
4672
        $repository = $this->getRepository();
4673
4674
        $contentId = $this->generateId('object', 12);
4675
        /* BEGIN: Use Case */
4676
        // $contentId is the ID of the "Administrator users" user group
4677
4678
        // Load content service
4679
        $contentService = $repository->getContentService();
4680
4681
        // Create a new user group draft
4682
        $draft = $contentService->createContentDraft(
4683
            $contentService->loadContentInfo($contentId)
4684
        );
4685
4686
        // Get an update struct and change the group name
4687
        $contentUpdate = $contentService->newContentUpdateStruct();
4688
        $contentUpdate->setField('name', 'Administrators', 'eng-US');
4689
4690
        // Start a transaction
4691
        $repository->beginTransaction();
4692
4693
        try {
4694
            // Update the group name
4695
            $draft = $contentService->updateContent(
4696
                $draft->getVersionInfo(),
4697
                $contentUpdate
4698
            );
4699
4700
            // Publish updated version
4701
            $contentService->publishVersion($draft->getVersionInfo());
4702
4703
            // Commit all changes.
4704
            $repository->commit();
4705
        } catch (Exception $e) {
4706
            // Cleanup hanging transaction on error
4707
            $repository->rollback();
4708
            throw $e;
4709
        }
4710
4711
        // Name is now "Administrators"
4712
        $name = $contentService->loadContent($contentId)->getFieldValue('name', 'eng-US');
4713
        /* END: Use Case */
4714
4715
        $this->assertEquals('Administrators', $name);
4716
    }
4717
4718
    /**
4719
     * Test for the updateContentMetadata() method.
4720
     *
4721
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4722
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
4723
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4724
     */
4725 View Code Duplication
    public function testUpdateContentMetadataInTransactionWithRollback()
4726
    {
4727
        $repository = $this->getRepository();
4728
4729
        $contentId = $this->generateId('object', 12);
4730
        /* BEGIN: Use Case */
4731
        // $contentId is the ID of the "Administrator users" user group
4732
4733
        // Get the content service
4734
        $contentService = $repository->getContentService();
4735
4736
        // Load a ContentInfo object
4737
        $contentInfo = $contentService->loadContentInfo($contentId);
4738
4739
        // Store remoteId for later testing
4740
        $remoteId = $contentInfo->remoteId;
4741
4742
        // Start a transaction
4743
        $repository->beginTransaction();
4744
4745
        try {
4746
            // Get metadata update struct and change remoteId
4747
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4748
            $metadataUpdate->remoteId = md5(microtime(true));
4749
4750
            // Update the metadata of the published content object
4751
            $contentService->updateContentMetadata(
4752
                $contentInfo,
4753
                $metadataUpdate
4754
            );
4755
        } catch (Exception $e) {
4756
            // Cleanup hanging transaction on error
4757
            $repository->rollback();
4758
            throw $e;
4759
        }
4760
4761
        // Rollback all changes.
4762
        $repository->rollback();
4763
4764
        // Load current remoteId
4765
        $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4766
        /* END: Use Case */
4767
4768
        $this->assertEquals($remoteId, $remoteIdReloaded);
4769
    }
4770
4771
    /**
4772
     * Test for the updateContentMetadata() method.
4773
     *
4774
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4775
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
4776
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4777
     */
4778 View Code Duplication
    public function testUpdateContentMetadataInTransactionWithCommit()
4779
    {
4780
        $repository = $this->getRepository();
4781
4782
        $contentId = $this->generateId('object', 12);
4783
        /* BEGIN: Use Case */
4784
        // $contentId is the ID of the "Administrator users" user group
4785
4786
        // Get the content service
4787
        $contentService = $repository->getContentService();
4788
4789
        // Load a ContentInfo object
4790
        $contentInfo = $contentService->loadContentInfo($contentId);
4791
4792
        // Store remoteId for later testing
4793
        $remoteId = $contentInfo->remoteId;
4794
4795
        // Start a transaction
4796
        $repository->beginTransaction();
4797
4798
        try {
4799
            // Get metadata update struct and change remoteId
4800
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4801
            $metadataUpdate->remoteId = md5(microtime(true));
4802
4803
            // Update the metadata of the published content object
4804
            $contentService->updateContentMetadata(
4805
                $contentInfo,
4806
                $metadataUpdate
4807
            );
4808
4809
            // Commit all changes.
4810
            $repository->commit();
4811
        } catch (Exception $e) {
4812
            // Cleanup hanging transaction on error
4813
            $repository->rollback();
4814
            throw $e;
4815
        }
4816
4817
        // Load current remoteId
4818
        $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4819
        /* END: Use Case */
4820
4821
        $this->assertNotEquals($remoteId, $remoteIdReloaded);
4822
    }
4823
4824
    /**
4825
     * Test for the deleteVersion() method.
4826
     *
4827
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
4828
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4829
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4830
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
4831
     */
4832 View Code Duplication
    public function testDeleteVersionInTransactionWithRollback()
4833
    {
4834
        $repository = $this->getRepository();
4835
4836
        $contentId = $this->generateId('object', 12);
4837
        /* BEGIN: Use Case */
4838
        // $contentId is the ID of the "Administrator users" user group
4839
4840
        // Get the content service
4841
        $contentService = $repository->getContentService();
4842
4843
        // Start a new transaction
4844
        $repository->beginTransaction();
4845
4846
        try {
4847
            // Create a new draft
4848
            $draft = $contentService->createContentDraft(
4849
                $contentService->loadContentInfo($contentId)
4850
            );
4851
4852
            $contentService->deleteVersion($draft->getVersionInfo());
4853
        } catch (Exception $e) {
4854
            // Cleanup hanging transaction on error
4855
            $repository->rollback();
4856
            throw $e;
4857
        }
4858
4859
        // Rollback all changes.
4860
        $repository->rollback();
4861
4862
        // This array will be empty
4863
        $drafts = $contentService->loadContentDrafts();
4864
        /* END: Use Case */
4865
4866
        $this->assertSame([], $drafts);
4867
    }
4868
4869
    /**
4870
     * Test for the deleteVersion() method.
4871
     *
4872
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
4873
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4874
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4875
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
4876
     */
4877 View Code Duplication
    public function testDeleteVersionInTransactionWithCommit()
4878
    {
4879
        $repository = $this->getRepository();
4880
4881
        $contentId = $this->generateId('object', 12);
4882
        /* BEGIN: Use Case */
4883
        // $contentId is the ID of the "Administrator users" user group
4884
4885
        // Get the content service
4886
        $contentService = $repository->getContentService();
4887
4888
        // Start a new transaction
4889
        $repository->beginTransaction();
4890
4891
        try {
4892
            // Create a new draft
4893
            $draft = $contentService->createContentDraft(
4894
                $contentService->loadContentInfo($contentId)
4895
            );
4896
4897
            $contentService->deleteVersion($draft->getVersionInfo());
4898
4899
            // Commit all changes.
4900
            $repository->commit();
4901
        } catch (Exception $e) {
4902
            // Cleanup hanging transaction on error
4903
            $repository->rollback();
4904
            throw $e;
4905
        }
4906
4907
        // This array will contain no element
4908
        $drafts = $contentService->loadContentDrafts();
4909
        /* END: Use Case */
4910
4911
        $this->assertSame([], $drafts);
4912
    }
4913
4914
    /**
4915
     * Test for the deleteContent() method.
4916
     *
4917
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
4918
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
4919
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4920
     */
4921 View Code Duplication
    public function testDeleteContentInTransactionWithRollback()
4922
    {
4923
        $repository = $this->getRepository();
4924
4925
        $contentId = $this->generateId('object', 11);
4926
        /* BEGIN: Use Case */
4927
        // $contentId is the ID of the "Members" user group in an eZ Publish
4928
        // demo installation
4929
4930
        // Get content service
4931
        $contentService = $repository->getContentService();
4932
4933
        // Load a ContentInfo instance
4934
        $contentInfo = $contentService->loadContentInfo($contentId);
4935
4936
        // Start a new transaction
4937
        $repository->beginTransaction();
4938
4939
        try {
4940
            // Delete content object
4941
            $contentService->deleteContent($contentInfo);
4942
        } catch (Exception $e) {
4943
            // Cleanup hanging transaction on error
4944
            $repository->rollback();
4945
            throw $e;
4946
        }
4947
4948
        // Rollback all changes
4949
        $repository->rollback();
4950
4951
        // This call will return the original content object
4952
        $contentInfo = $contentService->loadContentInfo($contentId);
4953
        /* END: Use Case */
4954
4955
        $this->assertEquals($contentId, $contentInfo->id);
4956
    }
4957
4958
    /**
4959
     * Test for the deleteContent() method.
4960
     *
4961
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
4962
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
4963
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4964
     */
4965 View Code Duplication
    public function testDeleteContentInTransactionWithCommit()
4966
    {
4967
        $repository = $this->getRepository();
4968
4969
        $contentId = $this->generateId('object', 11);
4970
        /* BEGIN: Use Case */
4971
        // $contentId is the ID of the "Members" user group in an eZ Publish
4972
        // demo installation
4973
4974
        // Get content service
4975
        $contentService = $repository->getContentService();
4976
4977
        // Load a ContentInfo instance
4978
        $contentInfo = $contentService->loadContentInfo($contentId);
4979
4980
        // Start a new transaction
4981
        $repository->beginTransaction();
4982
4983
        try {
4984
            // Delete content object
4985
            $contentService->deleteContent($contentInfo);
4986
4987
            // Commit all changes
4988
            $repository->commit();
4989
        } catch (Exception $e) {
4990
            // Cleanup hanging transaction on error
4991
            $repository->rollback();
4992
            throw $e;
4993
        }
4994
4995
        // Deleted content info is not found anymore
4996
        try {
4997
            $contentService->loadContentInfo($contentId);
4998
        } catch (NotFoundException $e) {
4999
            return;
5000
        }
5001
        /* END: Use Case */
5002
5003
        $this->fail('Can still load ContentInfo after commit.');
5004
    }
5005
5006
    /**
5007
     * Test for the copyContent() method.
5008
     *
5009
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
5010
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
5011
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
5012
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
5013
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
5014
     */
5015 View Code Duplication
    public function testCopyContentInTransactionWithRollback()
5016
    {
5017
        $repository = $this->getRepository();
5018
5019
        $contentId = $this->generateId('object', 11);
5020
        $locationId = $this->generateId('location', 13);
5021
        /* BEGIN: Use Case */
5022
        // $contentId is the ID of the "Members" user group in an eZ Publish
5023
        // demo installation
5024
5025
        // $locationId is the ID of the "Administrator users" group location
5026
5027
        // Get services
5028
        $contentService = $repository->getContentService();
5029
        $locationService = $repository->getLocationService();
5030
5031
        // Load content object to copy
5032
        $content = $contentService->loadContent($contentId);
5033
5034
        // Create new target location
5035
        $locationCreate = $locationService->newLocationCreateStruct($locationId);
5036
5037
        // Start a new transaction
5038
        $repository->beginTransaction();
5039
5040
        try {
5041
            // Copy content with all versions and drafts
5042
            $contentService->copyContent(
5043
                $content->contentInfo,
5044
                $locationCreate
5045
            );
5046
        } catch (Exception $e) {
5047
            // Cleanup hanging transaction on error
5048
            $repository->rollback();
5049
            throw $e;
5050
        }
5051
5052
        // Rollback all changes
5053
        $repository->rollback();
5054
5055
        $this->refreshSearch($repository);
5056
5057
        // This array will only contain a single admin user object
5058
        $locations = $locationService->loadLocationChildren(
5059
            $locationService->loadLocation($locationId)
5060
        )->locations;
5061
        /* END: Use Case */
5062
5063
        $this->assertEquals(1, count($locations));
5064
    }
5065
5066
    /**
5067
     * Test for the copyContent() method.
5068
     *
5069
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
5070
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
5071
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
5072
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
5073
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
5074
     */
5075 View Code Duplication
    public function testCopyContentInTransactionWithCommit()
5076
    {
5077
        $repository = $this->getRepository();
5078
5079
        $contentId = $this->generateId('object', 11);
5080
        $locationId = $this->generateId('location', 13);
5081
        /* BEGIN: Use Case */
5082
        // $contentId is the ID of the "Members" user group in an eZ Publish
5083
        // demo installation
5084
5085
        // $locationId is the ID of the "Administrator users" group location
5086
5087
        // Get services
5088
        $contentService = $repository->getContentService();
5089
        $locationService = $repository->getLocationService();
5090
5091
        // Load content object to copy
5092
        $content = $contentService->loadContent($contentId);
5093
5094
        // Create new target location
5095
        $locationCreate = $locationService->newLocationCreateStruct($locationId);
5096
5097
        // Start a new transaction
5098
        $repository->beginTransaction();
5099
5100
        try {
5101
            // Copy content with all versions and drafts
5102
            $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...
5103
                $content->contentInfo,
5104
                $locationCreate
5105
            );
5106
5107
            // Commit all changes
5108
            $repository->commit();
5109
        } catch (Exception $e) {
5110
            // Cleanup hanging transaction on error
5111
            $repository->rollback();
5112
            throw $e;
5113
        }
5114
5115
        $this->refreshSearch($repository);
5116
5117
        // This will contain the admin user and the new child location
5118
        $locations = $locationService->loadLocationChildren(
5119
            $locationService->loadLocation($locationId)
5120
        )->locations;
5121
        /* END: Use Case */
5122
5123
        $this->assertEquals(2, count($locations));
5124
    }
5125
5126
    public function testURLAliasesCreatedForNewContent()
5127
    {
5128
        $repository = $this->getRepository();
5129
5130
        $contentService = $repository->getContentService();
5131
        $locationService = $repository->getLocationService();
5132
        $urlAliasService = $repository->getURLAliasService();
5133
5134
        /* BEGIN: Use Case */
5135
        $draft = $this->createContentDraftVersion1();
5136
5137
        // Automatically creates a new URLAlias for the content
5138
        $liveContent = $contentService->publishVersion($draft->getVersionInfo());
5139
        /* END: Use Case */
5140
5141
        $location = $locationService->loadLocation(
5142
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5143
        );
5144
5145
        $aliases = $urlAliasService->listLocationAliases($location, false);
5146
5147
        $this->assertAliasesCorrect(
5148
            [
5149
                '/Design/Plain-site/An-awesome-forum' => [
5150
                    'type' => URLAlias::LOCATION,
5151
                    'destination' => $location->id,
5152
                    'path' => '/Design/Plain-site/An-awesome-forum',
5153
                    'languageCodes' => ['eng-US'],
5154
                    'isHistory' => false,
5155
                    'isCustom' => false,
5156
                    'forward' => false,
5157
                ],
5158
            ],
5159
            $aliases
5160
        );
5161
    }
5162
5163
    public function testURLAliasesCreatedForUpdatedContent()
5164
    {
5165
        $repository = $this->getRepository();
5166
5167
        $contentService = $repository->getContentService();
5168
        $locationService = $repository->getLocationService();
5169
        $urlAliasService = $repository->getURLAliasService();
5170
5171
        /* BEGIN: Use Case */
5172
        $draft = $this->createUpdatedDraftVersion2();
5173
5174
        $location = $locationService->loadLocation(
5175
            $draft->getVersionInfo()->getContentInfo()->mainLocationId
5176
        );
5177
5178
        // Load and assert URL aliases before publishing updated Content, so that
5179
        // SPI cache is warmed up and cache invalidation is also tested.
5180
        $aliases = $urlAliasService->listLocationAliases($location, false);
5181
5182
        $this->assertAliasesCorrect(
5183
            [
5184
                '/Design/Plain-site/An-awesome-forum' => [
5185
                    'type' => URLAlias::LOCATION,
5186
                    'destination' => $location->id,
5187
                    'path' => '/Design/Plain-site/An-awesome-forum',
5188
                    'languageCodes' => ['eng-US'],
5189
                    'alwaysAvailable' => true,
5190
                    'isHistory' => false,
5191
                    'isCustom' => false,
5192
                    'forward' => false,
5193
                ],
5194
            ],
5195
            $aliases
5196
        );
5197
5198
        // Automatically marks old aliases for the content as history
5199
        // and creates new aliases, based on the changes
5200
        $liveContent = $contentService->publishVersion($draft->getVersionInfo());
5201
        /* END: Use Case */
5202
5203
        $location = $locationService->loadLocation(
5204
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5205
        );
5206
5207
        $aliases = $urlAliasService->listLocationAliases($location, false);
5208
5209
        $this->assertAliasesCorrect(
5210
            [
5211
                '/Design/Plain-site/An-awesome-forum2' => [
5212
                    'type' => URLAlias::LOCATION,
5213
                    'destination' => $location->id,
5214
                    'path' => '/Design/Plain-site/An-awesome-forum2',
5215
                    'languageCodes' => ['eng-US'],
5216
                    'alwaysAvailable' => true,
5217
                    'isHistory' => false,
5218
                    'isCustom' => false,
5219
                    'forward' => false,
5220
                ],
5221
                '/Design/Plain-site/An-awesome-forum23' => [
5222
                    'type' => URLAlias::LOCATION,
5223
                    'destination' => $location->id,
5224
                    'path' => '/Design/Plain-site/An-awesome-forum23',
5225
                    'languageCodes' => ['eng-GB'],
5226
                    'alwaysAvailable' => true,
5227
                    'isHistory' => false,
5228
                    'isCustom' => false,
5229
                    'forward' => false,
5230
                ],
5231
            ],
5232
            $aliases
5233
        );
5234
    }
5235
5236
    public function testCustomURLAliasesNotHistorizedOnUpdatedContent()
5237
    {
5238
        $repository = $this->getRepository();
5239
5240
        $contentService = $repository->getContentService();
5241
5242
        /* BEGIN: Use Case */
5243
        $urlAliasService = $repository->getURLAliasService();
5244
        $locationService = $repository->getLocationService();
5245
5246
        $content = $this->createContentVersion1();
5247
5248
        // Create a custom URL alias
5249
        $urlAliasService->createUrlAlias(
5250
            $locationService->loadLocation(
5251
                $content->getVersionInfo()->getContentInfo()->mainLocationId
5252
            ),
5253
            '/my/fancy/story-about-ez-publish',
5254
            'eng-US'
5255
        );
5256
5257
        $draftVersion2 = $contentService->createContentDraft($content->contentInfo);
5258
5259
        $contentUpdate = $contentService->newContentUpdateStruct();
5260
        $contentUpdate->initialLanguageCode = 'eng-US';
5261
        $contentUpdate->setField('name', 'Amazing Bielefeld forum');
5262
5263
        $draftVersion2 = $contentService->updateContent(
5264
            $draftVersion2->getVersionInfo(),
5265
            $contentUpdate
5266
        );
5267
5268
        // Only marks auto-generated aliases as history
5269
        // the custom one is left untouched
5270
        $liveContent = $contentService->publishVersion($draftVersion2->getVersionInfo());
5271
        /* END: Use Case */
5272
5273
        $location = $locationService->loadLocation(
5274
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5275
        );
5276
5277
        $aliases = $urlAliasService->listLocationAliases($location);
5278
5279
        $this->assertAliasesCorrect(
5280
            [
5281
                '/my/fancy/story-about-ez-publish' => [
5282
                    'type' => URLAlias::LOCATION,
5283
                    'destination' => $location->id,
5284
                    'path' => '/my/fancy/story-about-ez-publish',
5285
                    'languageCodes' => ['eng-US'],
5286
                    'isHistory' => false,
5287
                    'isCustom' => true,
5288
                    'forward' => false,
5289
                    'alwaysAvailable' => false,
5290
                ],
5291
            ],
5292
            $aliases
5293
        );
5294
    }
5295
5296
    /**
5297
     * Test to ensure that old versions are not affected by updates to newer
5298
     * drafts.
5299
     */
5300
    public function testUpdatingDraftDoesNotUpdateOldVersions()
5301
    {
5302
        $repository = $this->getRepository();
5303
5304
        $contentService = $repository->getContentService();
5305
5306
        $contentVersion2 = $this->createContentVersion2();
5307
5308
        $loadedContent1 = $contentService->loadContent($contentVersion2->id, null, 1);
5309
        $loadedContent2 = $contentService->loadContent($contentVersion2->id, null, 2);
5310
5311
        $this->assertNotEquals(
5312
            $loadedContent1->getFieldValue('name', 'eng-US'),
5313
            $loadedContent2->getFieldValue('name', 'eng-US')
5314
        );
5315
    }
5316
5317
    /**
5318
     * Test scenario with writer and publisher users.
5319
     * Writer can only create content. Publisher can publish this content.
5320
     */
5321
    public function testPublishWorkflow()
5322
    {
5323
        $repository = $this->getRepository();
5324
        $contentService = $repository->getContentService();
5325
5326
        $this->createRoleWithPolicies('Publisher', [
5327
            ['module' => 'content', 'function' => 'read'],
5328
            ['module' => 'content', 'function' => 'create'],
5329
            ['module' => 'content', 'function' => 'publish'],
5330
        ]);
5331
5332
        $this->createRoleWithPolicies('Writer', [
5333
            ['module' => 'content', 'function' => 'read'],
5334
            ['module' => 'content', 'function' => 'create'],
5335
        ]);
5336
5337
        $writerUser = $this->createCustomUserWithLogin(
5338
            'writer',
5339
            '[email protected]',
5340
            'Writers',
5341
            'Writer'
5342
        );
5343
5344
        $publisherUser = $this->createCustomUserWithLogin(
5345
            'publisher',
5346
            '[email protected]',
5347
            'Publishers',
5348
            'Publisher'
5349
        );
5350
5351
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5352
        $draft = $this->createContentDraftVersion1();
5353
5354
        $repository->getPermissionResolver()->setCurrentUserReference($publisherUser);
5355
        $content = $contentService->publishVersion($draft->versionInfo);
5356
5357
        $contentService->loadContent($content->id);
5358
    }
5359
5360
    /**
5361
     * Test publish / content policy is required to be able to publish content.
5362
     *
5363
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
5364
     * @expectedExceptionMessageRegExp /User does not have access to 'publish' 'content'/
5365
     */
5366
    public function testPublishContentWithoutPublishPolicyThrowsException()
5367
    {
5368
        $repository = $this->getRepository();
5369
5370
        $this->createRoleWithPolicies('Writer', [
5371
            ['module' => 'content', 'function' => 'read'],
5372
            ['module' => 'content', 'function' => 'create'],
5373
            ['module' => 'content', 'function' => 'edit'],
5374
        ]);
5375
        $writerUser = $this->createCustomUserWithLogin(
5376
            'writer',
5377
            '[email protected]',
5378
            'Writers',
5379
            'Writer'
5380
        );
5381
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5382
5383
        $this->createContentVersion1();
5384
    }
5385
5386
    /**
5387
     * Test removal of the specific translation from all the Versions of a Content Object.
5388
     *
5389
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5390
     */
5391 View Code Duplication
    public function testDeleteTranslation()
5392
    {
5393
        $repository = $this->getRepository();
5394
        $contentService = $repository->getContentService();
5395
        $content = $this->createContentVersion2();
5396
5397
        // create multiple versions to exceed archive limit
5398
        for ($i = 0; $i < 5; ++$i) {
5399
            $contentDraft = $contentService->createContentDraft($content->contentInfo);
5400
            $contentUpdateStruct = $contentService->newContentUpdateStruct();
5401
            $contentDraft = $contentService->updateContent(
5402
                $contentDraft->versionInfo,
5403
                $contentUpdateStruct
5404
            );
5405
            $contentService->publishVersion($contentDraft->versionInfo);
5406
        }
5407
5408
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5409
5410
        $this->assertTranslationDoesNotExist('eng-GB', $content->id);
5411
    }
5412
5413
    /**
5414
     * Test deleting a Translation which is initial for some Version, updates initialLanguageCode
5415
     * with mainLanguageCode (assuming they are different).
5416
     */
5417
    public function testDeleteTranslationUpdatesInitialLanguageCodeVersion()
5418
    {
5419
        $repository = $this->getRepository();
5420
        $contentService = $repository->getContentService();
5421
5422
        $content = $this->createContentVersion2();
5423
        // create another, copied, version
5424
        $contentDraft = $contentService->updateContent(
5425
            $contentService->createContentDraft($content->contentInfo)->versionInfo,
5426
            $contentService->newContentUpdateStruct()
5427
        );
5428
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
5429
5430
        // remove first version with only one translation as it is not the subject of this test
5431
        $contentService->deleteVersion(
5432
            $contentService->loadVersionInfo($publishedContent->contentInfo, 1)
5433
        );
5434
5435
        // sanity check
5436
        self::assertEquals('eng-US', $content->contentInfo->mainLanguageCode);
5437
        self::assertEquals('eng-US', $content->versionInfo->initialLanguageCode);
5438
5439
        // update mainLanguageCode so it is different than initialLanguageCode for Version
5440
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5441
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5442
        $content = $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
5443
5444
        $contentService->deleteTranslation($content->contentInfo, 'eng-US');
5445
5446
        $this->assertTranslationDoesNotExist('eng-US', $content->id);
5447
    }
5448
5449
    /**
5450
     * Test removal of the specific translation properly updates languages of the URL alias.
5451
     *
5452
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5453
     */
5454
    public function testDeleteTranslationUpdatesUrlAlias()
5455
    {
5456
        $repository = $this->getRepository();
5457
        $contentService = $repository->getContentService();
5458
        $locationService = $repository->getLocationService();
5459
        $urlAliasService = $repository->getURLAliasService();
5460
5461
        $content = $this->createContentVersion2();
5462
        $mainLocation = $locationService->loadLocation($content->contentInfo->mainLocationId);
5463
5464
        // create custom URL alias for Content main Location
5465
        $urlAliasService->createUrlAlias($mainLocation, '/my-custom-url', 'eng-GB');
5466
5467
        // create secondary Location for Content
5468
        $secondaryLocation = $locationService->createLocation(
5469
            $content->contentInfo,
5470
            $locationService->newLocationCreateStruct(2)
5471
        );
5472
5473
        // create custom URL alias for Content secondary Location
5474
        $urlAliasService->createUrlAlias($secondaryLocation, '/my-secondary-url', 'eng-GB');
5475
5476
        // delete Translation
5477
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5478
5479
        foreach ([$mainLocation, $secondaryLocation] as $location) {
5480
            // check auto-generated URL aliases
5481
            foreach ($urlAliasService->listLocationAliases($location, false) as $alias) {
5482
                self::assertNotContains('eng-GB', $alias->languageCodes);
5483
            }
5484
5485
            // check custom URL aliases
5486
            foreach ($urlAliasService->listLocationAliases($location) as $alias) {
5487
                self::assertNotContains('eng-GB', $alias->languageCodes);
5488
            }
5489
        }
5490
    }
5491
5492
    /**
5493
     * Test removal of a main translation throws BadStateException.
5494
     *
5495
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5496
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5497
     * @expectedExceptionMessage Specified translation is the main translation of the Content Object
5498
     */
5499
    public function testDeleteTranslationMainLanguageThrowsBadStateException()
5500
    {
5501
        $repository = $this->getRepository();
5502
        $contentService = $repository->getContentService();
5503
        $content = $this->createContentVersion2();
5504
5505
        // delete first version which has only one translation
5506
        $contentService->deleteVersion($contentService->loadVersionInfo($content->contentInfo, 1));
5507
5508
        // try to delete main translation
5509
        $contentService->deleteTranslation($content->contentInfo, $content->contentInfo->mainLanguageCode);
5510
    }
5511
5512
    /**
5513
     * Test removal of a Translation is possible when some archived Versions have only this Translation.
5514
     *
5515
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5516
     */
5517
    public function testDeleteTranslationDeletesSingleTranslationVersions()
5518
    {
5519
        $repository = $this->getRepository();
5520
        $contentService = $repository->getContentService();
5521
        // content created by the createContentVersion1 method has eng-US translation only.
5522
        $content = $this->createContentVersion1();
5523
5524
        // create new version and add eng-GB translation
5525
        $contentDraft = $contentService->createContentDraft($content->contentInfo);
5526
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
5527
        $contentUpdateStruct->setField('name', 'Awesome Board', 'eng-GB');
5528
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
5529
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
5530
5531
        // update mainLanguageCode to avoid exception related to that
5532
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5533
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5534
5535
        $content = $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
5536
5537
        $contentService->deleteTranslation($content->contentInfo, 'eng-US');
5538
5539
        $this->assertTranslationDoesNotExist('eng-US', $content->id);
5540
    }
5541
5542
    /**
5543
     * Test removal of the translation by the user who is not allowed to delete a content
5544
     * throws UnauthorizedException.
5545
     *
5546
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5547
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5548
     * @expectedExceptionMessage User does not have access to 'remove' 'content'
5549
     */
5550
    public function testDeleteTranslationThrowsUnauthorizedException()
5551
    {
5552
        $repository = $this->getRepository();
5553
        $contentService = $repository->getContentService();
5554
5555
        $content = $this->createContentVersion2();
5556
5557
        // create user that can read/create/edit but cannot delete content
5558
        $this->createRoleWithPolicies('Writer', [
5559
            ['module' => 'content', 'function' => 'read'],
5560
            ['module' => 'content', 'function' => 'versionread'],
5561
            ['module' => 'content', 'function' => 'create'],
5562
            ['module' => 'content', 'function' => 'edit'],
5563
        ]);
5564
        $writerUser = $this->createCustomUserWithLogin(
5565
            'writer',
5566
            '[email protected]',
5567
            'Writers',
5568
            'Writer'
5569
        );
5570
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5571
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5572
    }
5573
5574
    /**
5575
     * Test removal of a non-existent translation throws InvalidArgumentException.
5576
     *
5577
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5578
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5579
     * @expectedExceptionMessage Argument '$languageCode' is invalid: ger-DE does not exist in the Content item
5580
     */
5581
    public function testDeleteTranslationThrowsInvalidArgumentException()
5582
    {
5583
        $repository = $this->getRepository();
5584
        $contentService = $repository->getContentService();
5585
        // content created by the createContentVersion1 method has eng-US translation only.
5586
        $content = $this->createContentVersion1();
5587
        $contentService->deleteTranslation($content->contentInfo, 'ger-DE');
5588
    }
5589
5590
    /**
5591
     * Test deleting a Translation from Draft.
5592
     *
5593
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5594
     */
5595
    public function testDeleteTranslationFromDraft()
5596
    {
5597
        $repository = $this->getRepository();
5598
        $contentService = $repository->getContentService();
5599
5600
        $languageCode = 'eng-GB';
5601
        $content = $this->createMultipleLanguageContentVersion2();
5602
        $draft = $contentService->createContentDraft($content->contentInfo);
5603
        $draft = $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5604
        $content = $contentService->publishVersion($draft->versionInfo);
5605
5606
        $loadedContent = $contentService->loadContent($content->id);
5607
        self::assertNotContains($languageCode, $loadedContent->versionInfo->languageCodes);
5608
        self::assertEmpty($loadedContent->getFieldsByLanguage($languageCode));
5609
    }
5610
5611
    /**
5612
     * Get values for multilingual field.
5613
     *
5614
     * @return array
5615
     */
5616
    public function providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing()
5617
    {
5618
        return [
5619
            [
5620
                ['eng-US' => 'US Name', 'eng-GB' => 'GB Name'],
5621
            ],
5622
            [
5623
                ['eng-US' => 'Same Name', 'eng-GB' => 'Same Name'],
5624
            ],
5625
        ];
5626
    }
5627
5628
    /**
5629
     * Test deleting a Translation from Draft removes previously stored URL aliases for published Content.
5630
     *
5631
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5632
     *
5633
     * @dataProvider providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing
5634
     *
5635
     * @param string[] $fieldValues translated field values
5636
     *
5637
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
5638
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5639
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
5640
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5641
     */
5642
    public function testDeleteTranslationFromDraftRemovesUrlAliasOnPublishing(array $fieldValues)
5643
    {
5644
        $repository = $this->getRepository();
5645
        $contentService = $repository->getContentService();
5646
        $locationService = $repository->getLocationService();
5647
        $urlAliasService = $repository->getURLAliasService();
5648
5649
        // set language code to be removed
5650
        $languageCode = 'eng-GB';
5651
        $draft = $this->createMultilingualContentDraft(
5652
            'folder',
5653
            2,
5654
            'eng-US',
5655
            [
5656
                'name' => [
5657
                    'eng-GB' => $fieldValues['eng-GB'],
5658
                    'eng-US' => $fieldValues['eng-US'],
5659
                ],
5660
            ]
5661
        );
5662
        $content = $contentService->publishVersion($draft->versionInfo);
5663
5664
        // create secondary location
5665
        $locationService->createLocation(
5666
            $content->contentInfo,
5667
            $locationService->newLocationCreateStruct(5)
5668
        );
5669
5670
        // sanity check
5671
        $locations = $locationService->loadLocations($content->contentInfo);
5672
        self::assertCount(2, $locations, 'Sanity check: Expected to find 2 Locations');
5673
        foreach ($locations as $location) {
5674
            $urlAliasService->createUrlAlias($location, '/us-custom_' . $location->id, 'eng-US');
5675
            $urlAliasService->createUrlAlias($location, '/gb-custom_' . $location->id, 'eng-GB');
5676
5677
            // check default URL aliases
5678
            $aliases = $urlAliasService->listLocationAliases($location, false, $languageCode);
5679
            self::assertNotEmpty($aliases, 'Sanity check: URL alias for the translation does not exist');
5680
5681
            // check custom URL aliases
5682
            $aliases = $urlAliasService->listLocationAliases($location, true, $languageCode);
5683
            self::assertNotEmpty($aliases, 'Sanity check: Custom URL alias for the translation does not exist');
5684
        }
5685
5686
        // delete translation and publish new version
5687
        $draft = $contentService->createContentDraft($content->contentInfo);
5688
        $draft = $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5689
        $contentService->publishVersion($draft->versionInfo);
5690
5691
        // check that aliases does not exist
5692
        foreach ($locations as $location) {
5693
            // check default URL aliases
5694
            $aliases = $urlAliasService->listLocationAliases($location, false, $languageCode);
5695
            self::assertEmpty($aliases, 'URL alias for the deleted translation still exists');
5696
5697
            // check custom URL aliases
5698
            $aliases = $urlAliasService->listLocationAliases($location, true, $languageCode);
5699
            self::assertEmpty($aliases, 'Custom URL alias for the deleted translation still exists');
5700
        }
5701
    }
5702
5703
    /**
5704
     * Test that URL aliases for deleted Translations are properly archived.
5705
     */
5706
    public function testDeleteTranslationFromDraftArchivesUrlAliasOnPublishing()
5707
    {
5708
        $repository = $this->getRepository();
5709
        $contentService = $repository->getContentService();
5710
        $urlAliasService = $repository->getURLAliasService();
5711
5712
        $content = $contentService->publishVersion(
5713
            $this->createMultilingualContentDraft(
5714
                'folder',
5715
                2,
5716
                'eng-US',
5717
                [
5718
                    'name' => [
5719
                        'eng-GB' => 'BritishEnglishContent',
5720
                        'eng-US' => 'AmericanEnglishContent',
5721
                    ],
5722
                ]
5723
            )->versionInfo
5724
        );
5725
5726
        $unrelatedContent = $contentService->publishVersion(
5727
            $this->createMultilingualContentDraft(
5728
                'folder',
5729
                2,
5730
                'eng-US',
5731
                [
5732
                    'name' => [
5733
                        'eng-GB' => 'AnotherBritishContent',
5734
                        'eng-US' => 'AnotherAmericanContent',
5735
                    ],
5736
                ]
5737
            )->versionInfo
5738
        );
5739
5740
        $urlAlias = $urlAliasService->lookup('/BritishEnglishContent');
5741
        self::assertFalse($urlAlias->isHistory);
5742
        self::assertEquals($urlAlias->path, '/BritishEnglishContent');
5743
        self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId);
5744
5745
        $draft = $contentService->deleteTranslationFromDraft(
5746
            $contentService->createContentDraft($content->contentInfo)->versionInfo,
5747
            'eng-GB'
5748
        );
5749
        $content = $contentService->publishVersion($draft->versionInfo);
5750
5751
        $urlAlias = $urlAliasService->lookup('/BritishEnglishContent');
5752
        self::assertTrue($urlAlias->isHistory);
5753
        self::assertEquals($urlAlias->path, '/BritishEnglishContent');
5754
        self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId);
5755
5756
        $unrelatedUrlAlias = $urlAliasService->lookup('/AnotherBritishContent');
5757
        self::assertFalse($unrelatedUrlAlias->isHistory);
5758
        self::assertEquals($unrelatedUrlAlias->path, '/AnotherBritishContent');
5759
        self::assertEquals($unrelatedUrlAlias->destination, $unrelatedContent->contentInfo->mainLocationId);
5760
    }
5761
5762
    /**
5763
     * Test deleting a Translation from Draft which has single Translation throws BadStateException.
5764
     *
5765
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5766
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5767
     * @expectedExceptionMessage Specified Translation is the only one Content Object Version has
5768
     */
5769
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnSingleTranslation()
5770
    {
5771
        $repository = $this->getRepository();
5772
        $contentService = $repository->getContentService();
5773
5774
        // create Content with single Translation
5775
        $publishedContent = $contentService->publishVersion(
5776
            $this->createContentDraft(
5777
                'forum',
5778
                2,
5779
                ['name' => 'Eng-US Version name']
5780
            )->versionInfo
5781
        );
5782
5783
        // update mainLanguageCode to avoid exception related to trying to delete main Translation
5784
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5785
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5786
        $publishedContent = $contentService->updateContentMetadata(
5787
            $publishedContent->contentInfo,
5788
            $contentMetadataUpdateStruct
5789
        );
5790
5791
        // create single Translation Version from the first one
5792
        $draft = $contentService->createContentDraft(
5793
            $publishedContent->contentInfo,
5794
            $publishedContent->versionInfo
5795
        );
5796
5797
        // attempt to delete Translation
5798
        $contentService->deleteTranslationFromDraft($draft->versionInfo, 'eng-US');
5799
    }
5800
5801
    /**
5802
     * Test deleting the Main Translation from Draft throws BadStateException.
5803
     *
5804
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5805
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5806
     * @expectedExceptionMessage Specified Translation is the main Translation of the Content Object
5807
     */
5808
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnMainTranslation()
5809
    {
5810
        $repository = $this->getRepository();
5811
        $contentService = $repository->getContentService();
5812
5813
        $mainLanguageCode = 'eng-US';
5814
        $draft = $this->createMultilingualContentDraft(
5815
            'forum',
5816
            2,
5817
            $mainLanguageCode,
5818
            [
5819
                'name' => [
5820
                    'eng-US' => 'An awesome eng-US forum',
5821
                    'eng-GB' => 'An awesome eng-GB forum',
5822
                ],
5823
            ]
5824
        );
5825
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $mainLanguageCode);
5826
    }
5827
5828
    /**
5829
     * Test deleting the Translation from Published Version throws BadStateException.
5830
     *
5831
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5832
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5833
     * @expectedExceptionMessage Version is not a draft
5834
     */
5835 View Code Duplication
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnPublishedVersion()
5836
    {
5837
        $repository = $this->getRepository();
5838
        $contentService = $repository->getContentService();
5839
5840
        $languageCode = 'eng-US';
5841
        $content = $this->createMultipleLanguageContentVersion2();
5842
        $draft = $contentService->createContentDraft($content->contentInfo);
5843
        $publishedContent = $contentService->publishVersion($draft->versionInfo);
5844
        $contentService->deleteTranslationFromDraft($publishedContent->versionInfo, $languageCode);
5845
    }
5846
5847
    /**
5848
     * Test deleting a Translation from Draft throws UnauthorizedException if user cannot edit Content.
5849
     *
5850
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5851
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5852
     * @expectedExceptionMessage User does not have access to 'edit' 'content'
5853
     */
5854
    public function testDeleteTranslationFromDraftThrowsUnauthorizedException()
5855
    {
5856
        $repository = $this->getRepository();
5857
        $contentService = $repository->getContentService();
5858
5859
        $languageCode = 'eng-GB';
5860
        $content = $this->createMultipleLanguageContentVersion2();
5861
        $draft = $contentService->createContentDraft($content->contentInfo);
5862
5863
        // create user that can read/create/delete but cannot edit or content
5864
        $this->createRoleWithPolicies('Writer', [
5865
            ['module' => 'content', 'function' => 'read'],
5866
            ['module' => 'content', 'function' => 'versionread'],
5867
            ['module' => 'content', 'function' => 'create'],
5868
            ['module' => 'content', 'function' => 'delete'],
5869
        ]);
5870
        $writerUser = $this->createCustomUserWithLogin(
5871
            'user',
5872
            '[email protected]',
5873
            'Writers',
5874
            'Writer'
5875
        );
5876
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5877
5878
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5879
    }
5880
5881
    /**
5882
     * Test deleting a non-existent Translation from Draft throws InvalidArgumentException.
5883
     *
5884
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5885
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5886
     * @expectedExceptionMessageRegExp /The Version \(ContentId=\d+, VersionNo=\d+\) is not translated into ger-DE/
5887
     */
5888
    public function testDeleteTranslationFromDraftThrowsInvalidArgumentException()
5889
    {
5890
        $repository = $this->getRepository();
5891
        $contentService = $repository->getContentService();
5892
5893
        $languageCode = 'ger-DE';
5894
        $content = $this->createMultipleLanguageContentVersion2();
5895
        $draft = $contentService->createContentDraft($content->contentInfo);
5896
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5897
    }
5898
5899
    /**
5900
     * Test loading list of Content items.
5901
     */
5902
    public function testLoadContentListByContentInfo()
5903
    {
5904
        $repository = $this->getRepository();
5905
        $contentService = $repository->getContentService();
5906
        $locationService = $repository->getLocationService();
5907
5908
        $allLocationsCount = $locationService->getAllLocationsCount();
5909
        $contentInfoList = array_map(
5910
            function (Location $location) {
5911
                return $location->contentInfo;
5912
            },
5913
            $locationService->loadAllLocations(0, $allLocationsCount)
5914
        );
5915
5916
        $contentList = $contentService->loadContentListByContentInfo($contentInfoList);
5917
        self::assertCount(count($contentInfoList), $contentList);
5918
        foreach ($contentList as $content) {
5919
            try {
5920
                $loadedContent = $contentService->loadContent($content->id);
5921
                self::assertEquals($loadedContent, $content, "Failed to properly bulk-load Content {$content->id}");
5922
            } catch (NotFoundException $e) {
5923
                self::fail("Failed to load Content {$content->id}: {$e->getMessage()}");
5924
            } catch (UnauthorizedException $e) {
5925
                self::fail("Failed to load Content {$content->id}: {$e->getMessage()}");
5926
            }
5927
        }
5928
    }
5929
5930
    /**
5931
     * Test loading content versions after removing exactly two drafts.
5932
     *
5933
     * @see https://jira.ez.no/browse/EZP-30271
5934
     *
5935
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteVersion
5936
     */
5937
    public function testLoadVersionsAfterDeletingTwoDrafts()
5938
    {
5939
        $repository = $this->getRepository();
5940
        $contentService = $repository->getContentService();
5941
5942
        $content = $this->createFolder(['eng-GB' => 'Foo'], 2);
5943
5944
        // First update and publish
5945
        $modifiedContent = $this->updateFolder($content, ['eng-GB' => 'Foo1']);
5946
        $content = $contentService->publishVersion($modifiedContent->versionInfo);
5947
5948
        // Second update and publish
5949
        $modifiedContent = $this->updateFolder($content, ['eng-GB' => 'Foo2']);
5950
        $content = $contentService->publishVersion($modifiedContent->versionInfo);
5951
5952
        // Create drafts
5953
        $this->updateFolder($content, ['eng-GB' => 'Foo3']);
5954
        $this->updateFolder($content, ['eng-GB' => 'Foo4']);
5955
5956
        $versions = $contentService->loadVersions($content->contentInfo);
5957
5958
        foreach ($versions as $key => $version) {
5959
            if ($version->isDraft()) {
5960
                $contentService->deleteVersion($version);
5961
                unset($versions[$key]);
5962
            }
5963
        }
5964
5965
        $this->assertEquals($versions, $contentService->loadVersions($content->contentInfo));
5966
    }
5967
5968
    /**
5969
     * Tests loading list of content versions of status draft.
5970
     */
5971
    public function testLoadVersionsOfStatusDraft()
5972
    {
5973
        $repository = $this->getRepository();
5974
5975
        $contentService = $repository->getContentService();
5976
5977
        $content = $this->createContentVersion1();
5978
5979
        $contentService->createContentDraft($content->contentInfo);
5980
        $contentService->createContentDraft($content->contentInfo);
5981
        $contentService->createContentDraft($content->contentInfo);
5982
5983
        $versions = $contentService->loadVersions($content->contentInfo, VersionInfo::STATUS_DRAFT);
5984
5985
        $this->assertSame(\count($versions), 3);
5986
    }
5987
5988
    /**
5989
     * Tests loading list of content versions of status archived.
5990
     */
5991
    public function testLoadVersionsOfStatusArchived()
5992
    {
5993
        $repository = $this->getRepository();
5994
5995
        $contentService = $repository->getContentService();
5996
5997
        $content = $this->createContentVersion1();
5998
5999
        $draft1 = $contentService->createContentDraft($content->contentInfo);
6000
        $contentService->publishVersion($draft1->versionInfo);
6001
6002
        $draft2 = $contentService->createContentDraft($content->contentInfo);
6003
        $contentService->publishVersion($draft2->versionInfo);
6004
6005
        $versions = $contentService->loadVersions($content->contentInfo, VersionInfo::STATUS_ARCHIVED);
6006
6007
        $this->assertSame(\count($versions), 2);
6008
    }
6009
6010
    /**
6011
     * Asserts that all aliases defined in $expectedAliasProperties with the
6012
     * given properties are available in $actualAliases and not more.
6013
     *
6014
     * @param array $expectedAliasProperties
6015
     * @param array $actualAliases
6016
     */
6017
    private function assertAliasesCorrect(array $expectedAliasProperties, array $actualAliases)
6018
    {
6019
        foreach ($actualAliases as $actualAlias) {
6020
            if (!isset($expectedAliasProperties[$actualAlias->path])) {
6021
                $this->fail(
6022
                    sprintf(
6023
                        'Alias with path "%s" in languages "%s" not expected.',
6024
                        $actualAlias->path,
6025
                        implode(', ', $actualAlias->languageCodes)
6026
                    )
6027
                );
6028
            }
6029
6030
            foreach ($expectedAliasProperties[$actualAlias->path] as $propertyName => $propertyValue) {
6031
                $this->assertEquals(
6032
                    $propertyValue,
6033
                    $actualAlias->$propertyName,
6034
                    sprintf(
6035
                        'Property $%s incorrect on alias with path "%s" in languages "%s".',
6036
                        $propertyName,
6037
                        $actualAlias->path,
6038
                        implode(', ', $actualAlias->languageCodes)
6039
                    )
6040
                );
6041
            }
6042
6043
            unset($expectedAliasProperties[$actualAlias->path]);
6044
        }
6045
6046
        if (!empty($expectedAliasProperties)) {
6047
            $this->fail(
6048
                sprintf(
6049
                    'Missing expected aliases with paths "%s".',
6050
                    implode('", "', array_keys($expectedAliasProperties))
6051
                )
6052
            );
6053
        }
6054
    }
6055
6056
    /**
6057
     * Asserts that the given fields are equal to the default fields fixture.
6058
     *
6059
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6060
     */
6061
    private function assertAllFieldsEquals(array $fields)
6062
    {
6063
        $actual = $this->normalizeFields($fields);
6064
        $expected = $this->normalizeFields($this->createFieldsFixture());
6065
6066
        $this->assertEquals($expected, $actual);
6067
    }
6068
6069
    /**
6070
     * Asserts that the given fields are equal to a language filtered set of the
6071
     * default fields fixture.
6072
     *
6073
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6074
     * @param string $languageCode
6075
     */
6076
    private function assertLocaleFieldsEquals(array $fields, $languageCode)
6077
    {
6078
        $actual = $this->normalizeFields($fields);
6079
6080
        $expected = [];
6081
        foreach ($this->normalizeFields($this->createFieldsFixture()) as $field) {
6082
            if ($field->languageCode !== $languageCode) {
6083
                continue;
6084
            }
6085
            $expected[] = $field;
6086
        }
6087
6088
        $this->assertEquals($expected, $actual);
6089
    }
6090
6091
    /**
6092
     * This method normalizes a set of fields and returns a normalized set.
6093
     *
6094
     * Normalization means it resets the storage specific field id to zero and
6095
     * it sorts the field by their identifier and their language code. In
6096
     * addition, the field value is removed, since this one depends on the
6097
     * specific FieldType, which is tested in a dedicated integration test.
6098
     *
6099
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6100
     *
6101
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6102
     */
6103
    private function normalizeFields(array $fields)
6104
    {
6105
        $normalized = [];
6106
        foreach ($fields as $field) {
6107
            $normalized[] = new Field(
6108
                [
6109
                    'id' => 0,
6110
                    'value' => ($field->value !== null ? true : null),
6111
                    'languageCode' => $field->languageCode,
6112
                    'fieldDefIdentifier' => $field->fieldDefIdentifier,
6113
                    'fieldTypeIdentifier' => $field->fieldTypeIdentifier,
6114
                ]
6115
            );
6116
        }
6117
        usort(
6118
            $normalized,
6119 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...
6120
                if (0 === ($return = strcasecmp($field1->fieldDefIdentifier, $field2->fieldDefIdentifier))) {
6121
                    return strcasecmp($field1->languageCode, $field2->languageCode);
6122
                }
6123
6124
                return $return;
6125
            }
6126
        );
6127
6128
        return $normalized;
6129
    }
6130
6131
    /**
6132
     * Returns a filtered set of the default fields fixture.
6133
     *
6134
     * @param string $languageCode
6135
     *
6136
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6137
     */
6138
    private function createLocaleFieldsFixture($languageCode)
6139
    {
6140
        $fields = [];
6141
        foreach ($this->createFieldsFixture() as $field) {
6142
            if (null === $field->languageCode || $languageCode === $field->languageCode) {
6143
                $fields[] = $field;
6144
            }
6145
        }
6146
6147
        return $fields;
6148
    }
6149
6150
    /**
6151
     * Asserts that given Content has default ContentStates.
6152
     *
6153
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
6154
     */
6155
    private function assertDefaultContentStates(ContentInfo $contentInfo)
6156
    {
6157
        $repository = $this->getRepository();
6158
        $objectStateService = $repository->getObjectStateService();
6159
6160
        $objectStateGroups = $objectStateService->loadObjectStateGroups();
6161
6162
        foreach ($objectStateGroups as $objectStateGroup) {
6163
            $contentState = $objectStateService->getContentState($contentInfo, $objectStateGroup);
6164
            foreach ($objectStateService->loadObjectStates($objectStateGroup) as $objectState) {
6165
                // Only check the first object state which is the default one.
6166
                $this->assertEquals(
6167
                    $objectState,
6168
                    $contentState
6169
                );
6170
                break;
6171
            }
6172
        }
6173
    }
6174
6175
    /**
6176
     * Assert that given Content has no references to a translation specified by the $languageCode.
6177
     *
6178
     * @param string $languageCode
6179
     * @param int $contentId
6180
     */
6181
    private function assertTranslationDoesNotExist($languageCode, $contentId)
6182
    {
6183
        $repository = $this->getRepository();
6184
        $contentService = $repository->getContentService();
6185
6186
        $content = $contentService->loadContent($contentId);
6187
6188
        foreach ($content->fields as $fieldIdentifier => $field) {
6189
            /** @var array $field */
6190
            self::assertArrayNotHasKey($languageCode, $field);
6191
            self::assertNotEquals($languageCode, $content->contentInfo->mainLanguageCode);
6192
            self::assertArrayNotHasKey($languageCode, $content->versionInfo->getNames());
6193
            self::assertNotEquals($languageCode, $content->versionInfo->initialLanguageCode);
6194
            self::assertNotContains($languageCode, $content->versionInfo->languageCodes);
6195
        }
6196
        foreach ($contentService->loadVersions($content->contentInfo) as $versionInfo) {
6197
            self::assertArrayNotHasKey($languageCode, $versionInfo->getNames());
6198
            self::assertNotEquals($languageCode, $versionInfo->contentInfo->mainLanguageCode);
6199
            self::assertNotEquals($languageCode, $versionInfo->initialLanguageCode);
6200
            self::assertNotContains($languageCode, $versionInfo->languageCodes);
6201
        }
6202
    }
6203
6204
    /**
6205
     * Returns the default fixture of fields used in most tests.
6206
     *
6207
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6208
     */
6209
    private function createFieldsFixture()
6210
    {
6211
        return [
6212
            new Field(
6213
                [
6214
                    'id' => 0,
6215
                    'value' => 'Foo',
6216
                    'languageCode' => 'eng-US',
6217
                    'fieldDefIdentifier' => 'description',
6218
                    'fieldTypeIdentifier' => 'ezrichtext',
6219
                ]
6220
            ),
6221
            new Field(
6222
                [
6223
                    'id' => 0,
6224
                    'value' => 'Bar',
6225
                    'languageCode' => 'eng-GB',
6226
                    'fieldDefIdentifier' => 'description',
6227
                    'fieldTypeIdentifier' => 'ezrichtext',
6228
                ]
6229
            ),
6230
            new Field(
6231
                [
6232
                    'id' => 0,
6233
                    'value' => 'An awesome multi-lang forum²',
6234
                    'languageCode' => 'eng-US',
6235
                    'fieldDefIdentifier' => 'name',
6236
                    'fieldTypeIdentifier' => 'ezstring',
6237
                ]
6238
            ),
6239
            new Field(
6240
                [
6241
                    'id' => 0,
6242
                    'value' => 'An awesome multi-lang forum²³',
6243
                    'languageCode' => 'eng-GB',
6244
                    'fieldDefIdentifier' => 'name',
6245
                    'fieldTypeIdentifier' => 'ezstring',
6246
                ]
6247
            ),
6248
        ];
6249
    }
6250
6251
    /**
6252
     * Gets expected property values for the "Media" ContentInfo ValueObject.
6253
     *
6254
     * @return array
6255
     */
6256 View Code Duplication
    private function getExpectedMediaContentInfoProperties()
6257
    {
6258
        return [
6259
            'id' => 41,
6260
            'contentTypeId' => 1,
6261
            'name' => 'Media',
6262
            'sectionId' => 3,
6263
            'currentVersionNo' => 1,
6264
            'published' => true,
6265
            'ownerId' => 14,
6266
            'modificationDate' => $this->createDateTime(1060695457),
6267
            'publishedDate' => $this->createDateTime(1060695457),
6268
            'alwaysAvailable' => 1,
6269
            'remoteId' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
6270
            'mainLanguageCode' => 'eng-US',
6271
            'mainLocationId' => 43,
6272
            'status' => ContentInfo::STATUS_PUBLISHED,
6273
        ];
6274
    }
6275
6276
    /**
6277
     * @covers \eZ\Publish\API\Repository\ContentService::hideContent
6278
     *
6279
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6280
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6281
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6282
     */
6283
    public function testHideContent(): void
6284
    {
6285
        $repository = $this->getRepository();
6286
        $contentTypeService = $repository->getContentTypeService();
6287
        $contentService = $repository->getContentService();
6288
        $locationService = $repository->getLocationService();
6289
6290
        $locationCreateStructs = array_map(
6291
            function (Location $parentLocation) use ($locationService) {
6292
                return $locationService->newLocationCreateStruct($parentLocation->id);
6293
            },
6294
            $this->createParentLocationsForHideReveal($locationService, 2)
6295
        );
6296
6297
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6298
6299
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6300
        $contentCreate->setField('name', 'Folder to hide');
6301
6302
        $content = $contentService->createContent(
6303
            $contentCreate,
6304
            $locationCreateStructs
6305
        );
6306
6307
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6308
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6309
6310
        // Sanity check
6311
        $this->assertCount(3, $locations);
6312
        $this->assertCount(0, $this->filterHiddenLocations($locations));
6313
6314
        /* BEGIN: Use Case */
6315
        $contentService->hideContent($publishedContent->contentInfo);
6316
        /* END: Use Case */
6317
6318
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6319
        $this->assertCount(3, $locations);
6320
        $this->assertCount(3, $this->filterHiddenLocations($locations));
6321
    }
6322
6323
    /**
6324
     * @covers \eZ\Publish\API\Repository\ContentService::revealContent
6325
     *
6326
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6327
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6328
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6329
     */
6330
    public function testRevealContent()
6331
    {
6332
        $repository = $this->getRepository();
6333
        $contentTypeService = $repository->getContentTypeService();
6334
        $contentService = $repository->getContentService();
6335
        $locationService = $repository->getLocationService();
6336
6337
        $locationCreateStructs = array_map(
6338
            function (Location $parentLocation) use ($locationService) {
6339
                return $locationService->newLocationCreateStruct($parentLocation->id);
6340
            },
6341
            $this->createParentLocationsForHideReveal($locationService, 2)
6342
        );
6343
6344
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6345
6346
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6347
        $contentCreate->setField('name', 'Folder to hide');
6348
6349
        $locationCreateStructs[0]->hidden = true;
6350
6351
        $content = $contentService->createContent(
6352
            $contentCreate,
6353
            $locationCreateStructs
6354
        );
6355
6356
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6357
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6358
6359
        // Sanity check
6360
        $hiddenLocations = $this->filterHiddenLocations($locations);
6361
        $this->assertCount(3, $locations);
6362
        $this->assertCount(1, $hiddenLocations);
6363
6364
        // BEGIN: Use Case
6365
        $contentService->hideContent($publishedContent->contentInfo);
6366
        $this->assertCount(
6367
            3,
6368
            $this->filterHiddenLocations(
6369
                $locationService->loadLocations($publishedContent->contentInfo)
6370
            )
6371
        );
6372
6373
        $contentService->revealContent($publishedContent->contentInfo);
6374
        // END: Use Case
6375
6376
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6377
        $hiddenLocationsAfterReveal = $this->filterHiddenLocations($locations);
6378
        $this->assertCount(3, $locations);
6379
        $this->assertCount(1, $hiddenLocationsAfterReveal);
6380
        $this->assertEquals($hiddenLocations, $hiddenLocationsAfterReveal);
6381
    }
6382
6383
    /**
6384
     * @depends testRevealContent
6385
     */
6386
    public function testRevealContentWithHiddenParent()
6387
    {
6388
        $repository = $this->getRepository();
6389
6390
        $contentTypeService = $repository->getContentTypeService();
6391
        $contentService = $repository->getContentService();
6392
        $locationService = $repository->getLocationService();
6393
6394
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6395
6396
        $contentNames = [
6397
            'Parent Content',
6398
            'Child (Nesting 1)',
6399
            'Child (Nesting 2)',
6400
            'Child (Nesting 3)',
6401
            'Child (Nesting 4)',
6402
        ];
6403
6404
        $parentLocation = $locationService->newLocationCreateStruct(
6405
            $this->generateId('location', 2)
6406
        );
6407
6408
        /** @var Content[] $contents */
6409
        $contents = [];
6410
6411 View Code Duplication
        foreach ($contentNames as $contentName) {
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...
6412
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6413
            $contentCreate->setField('name', $contentName);
6414
6415
            $content = $contentService->createContent($contentCreate, [$parentLocation]);
6416
            $contents[] = $publishedContent = $contentService->publishVersion($content->versionInfo);
6417
6418
            $parentLocation = $locationService->newLocationCreateStruct(
6419
                $this->generateId('location', $publishedContent->contentInfo->mainLocationId)
6420
            );
6421
        }
6422
6423
        $contentService->hideContent($contents[0]->contentInfo);
6424
        $contentService->hideContent($contents[2]->contentInfo);
6425
        $contentService->revealContent($contents[2]->contentInfo);
6426
6427
        $parentContent = $contentService->loadContent($contents[0]->id);
6428
        $parentLocation = $locationService->loadLocation($parentContent->contentInfo->mainLocationId);
6429
        $parentSublocations = $locationService->loadLocationList([
6430
            $contents[1]->contentInfo->mainLocationId,
6431
            $contents[2]->contentInfo->mainLocationId,
6432
            $contents[3]->contentInfo->mainLocationId,
6433
            $contents[4]->contentInfo->mainLocationId,
6434
        ]);
6435
6436
        // Parent remains invisible
6437
        self::assertTrue($parentLocation->invisible);
6438
6439
        // All parent sublocations remain invisible as well
6440
        foreach ($parentSublocations as $parentSublocation) {
6441
            self::assertTrue($parentSublocation->invisible);
6442
        }
6443
    }
6444
6445
    /**
6446
     * @depends testRevealContent
6447
     */
6448
    public function testRevealContentWithHiddenChildren()
6449
    {
6450
        $repository = $this->getRepository();
6451
6452
        $contentTypeService = $repository->getContentTypeService();
6453
        $contentService = $repository->getContentService();
6454
        $locationService = $repository->getLocationService();
6455
6456
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6457
6458
        $contentNames = [
6459
            'Parent Content',
6460
            'Child (Nesting 1)',
6461
            'Child (Nesting 2)',
6462
            'Child (Nesting 3)',
6463
            'Child (Nesting 4)',
6464
        ];
6465
6466
        $parentLocation = $locationService->newLocationCreateStruct(
6467
            $this->generateId('location', 2)
6468
        );
6469
6470
        /** @var Content[] $contents */
6471
        $contents = [];
6472
6473 View Code Duplication
        foreach ($contentNames as $contentName) {
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...
6474
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6475
            $contentCreate->setField('name', $contentName);
6476
6477
            $content = $contentService->createContent($contentCreate, [$parentLocation]);
6478
            $contents[] = $publishedContent = $contentService->publishVersion($content->versionInfo);
6479
6480
            $parentLocation = $locationService->newLocationCreateStruct(
6481
                $this->generateId('location', $publishedContent->contentInfo->mainLocationId)
6482
            );
6483
        }
6484
6485
        $contentService->hideContent($contents[0]->contentInfo);
6486
        $contentService->hideContent($contents[2]->contentInfo);
6487
        $contentService->revealContent($contents[0]->contentInfo);
6488
6489
        $directChildContent = $contentService->loadContent($contents[1]->id);
6490
        $directChildLocation = $locationService->loadLocation($directChildContent->contentInfo->mainLocationId);
6491
6492
        $childContent = $contentService->loadContent($contents[2]->id);
6493
        $childLocation = $locationService->loadLocation($childContent->contentInfo->mainLocationId);
6494
        $childSublocations = $locationService->loadLocationList([
6495
            $contents[3]->contentInfo->mainLocationId,
6496
            $contents[4]->contentInfo->mainLocationId,
6497
        ]);
6498
6499
        // Direct child content is not hidden
6500
        self::assertFalse($directChildContent->contentInfo->isHidden);
6501
6502
        // Direct child content location is still invisible
6503
        self::assertFalse($directChildLocation->invisible);
6504
6505
        // Child content is still hidden
6506
        self::assertTrue($childContent->contentInfo->isHidden);
6507
6508
        // Child content location is still invisible
6509
        self::assertTrue($childLocation->invisible);
6510
6511
        // All childs sublocations remain invisible as well
6512
        foreach ($childSublocations as $childSublocation) {
6513
            self::assertTrue($childSublocation->invisible);
6514
        }
6515
    }
6516
6517
    public function testHideContentWithParentLocation()
6518
    {
6519
        $repository = $this->getRepository();
6520
        $contentTypeService = $repository->getContentTypeService();
6521
6522
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6523
6524
        $contentService = $repository->getContentService();
6525
        $locationService = $repository->getLocationService();
6526
6527
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6528
        $contentCreate->setField('name', 'Parent');
6529
6530
        $content = $contentService->createContent(
6531
            $contentCreate,
6532
            [
6533
                $locationService->newLocationCreateStruct(
6534
                    $this->generateId('location', 2)
6535
                ),
6536
            ]
6537
        );
6538
6539
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6540
6541
        /* BEGIN: Use Case */
6542
        $contentService->hideContent($publishedContent->contentInfo);
6543
        /* END: Use Case */
6544
6545
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6546
6547
        $childContentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6548
        $childContentCreate->setField('name', 'Child');
6549
6550
        $childContent = $contentService->createContent(
6551
            $childContentCreate,
6552
            [
6553
                $locationService->newLocationCreateStruct(
6554
                    $locations[0]->id
6555
                ),
6556
            ]
6557
        );
6558
6559
        $publishedChildContent = $contentService->publishVersion($childContent->versionInfo);
6560
6561
        $childLocations = $locationService->loadLocations($publishedChildContent->contentInfo);
6562
6563
        $this->assertTrue($locations[0]->hidden);
6564
        $this->assertTrue($locations[0]->invisible);
6565
6566
        $this->assertFalse($childLocations[0]->hidden);
6567
        $this->assertTrue($childLocations[0]->invisible);
6568
    }
6569
6570
    public function testChangeContentName()
6571
    {
6572
        $repository = $this->getRepository();
6573
6574
        $contentService = $repository->getContentService();
6575
        $contentDraft = $this->createContentDraft(
6576
            'folder',
6577
            $this->generateId('location', 2),
6578
            [
6579
                'name' => 'Marco',
6580
            ]
6581
        );
6582
6583
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
6584
        $contentMetadataUpdateStruct = new ContentMetadataUpdateStruct([
6585
            'name' => 'Polo',
6586
        ]);
6587
        $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
6588
6589
        $updatedContent = $contentService->loadContent($publishedContent->id);
6590
6591
        $this->assertEquals('Marco', $publishedContent->contentInfo->name);
6592
        $this->assertEquals('Polo', $updatedContent->contentInfo->name);
6593
    }
6594
6595
    public function testCopyTranslationsFromPublishedToDraft()
6596
    {
6597
        $repository = $this->getRepository();
6598
6599
        $contentService = $repository->getContentService();
6600
6601
        $contentDraft = $this->createContentDraft(
6602
            'folder',
6603
            $this->generateId('location', 2),
6604
            [
6605
                'name' => 'Folder US',
6606
            ]
6607
        );
6608
6609
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
6610
6611
        $deDraft = $contentService->createContentDraft($publishedContent->contentInfo);
6612
6613
        $contentUpdateStruct = new ContentUpdateStruct([
6614
            'initialLanguageCode' => 'ger-DE',
6615
            'fields' => $contentDraft->getFields(),
6616
        ]);
6617
6618
        $contentUpdateStruct->setField('name', 'Folder GER', 'ger-DE');
6619
6620
        $deContent = $contentService->updateContent($deDraft->versionInfo, $contentUpdateStruct);
6621
6622
        $updatedContent = $contentService->loadContent($deContent->id, null, $deContent->versionInfo->versionNo);
6623
        $this->assertEquals(
6624
            [
6625
                'eng-US' => 'Folder US',
6626
                'ger-DE' => 'Folder GER',
6627
            ],
6628
            $updatedContent->fields['name']
6629
        );
6630
6631
        $gbDraft = $contentService->createContentDraft($publishedContent->contentInfo);
6632
6633
        $contentUpdateStruct = new ContentUpdateStruct([
6634
            'initialLanguageCode' => 'eng-GB',
6635
            'fields' => $contentDraft->getFields(),
6636
        ]);
6637
6638
        $contentUpdateStruct->setField('name', 'Folder GB', 'eng-GB');
6639
6640
        $gbContent = $contentService->updateContent($gbDraft->versionInfo, $contentUpdateStruct);
6641
        $contentService->publishVersion($gbDraft->versionInfo);
6642
        $updatedContent = $contentService->loadContent($gbContent->id, null, $gbContent->versionInfo->versionNo);
6643
        $this->assertEquals(
6644
            [
6645
                'eng-US' => 'Folder US',
6646
                'eng-GB' => 'Folder GB',
6647
            ],
6648
            $updatedContent->fields['name']
6649
        );
6650
6651
        $dePublished = $contentService->publishVersion($deDraft->versionInfo);
6652
        $this->assertEquals(
6653
            [
6654
                'eng-US' => 'Folder US',
6655
                'ger-DE' => 'Folder GER',
6656
                'eng-GB' => 'Folder GB',
6657
            ],
6658
            $dePublished->fields['name']
6659
        );
6660
    }
6661
6662
    /**
6663
     * Create structure of parent folders with Locations to be used for Content hide/reveal tests.
6664
     *
6665
     * @param \eZ\Publish\API\Repository\LocationService $locationService
6666
     * @param int $parentLocationId
6667
     *
6668
     * @return \eZ\Publish\API\Repository\Values\Content\Location[] A list of Locations aimed to be parents
6669
     *
6670
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6671
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6672
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6673
     */
6674
    private function createParentLocationsForHideReveal(LocationService $locationService, int $parentLocationId): array
6675
    {
6676
        $parentFoldersLocationsIds = [
6677
            $this->createFolder(['eng-US' => 'P1'], $parentLocationId)->contentInfo->mainLocationId,
6678
            $this->createFolder(['eng-US' => 'P2'], $parentLocationId)->contentInfo->mainLocationId,
6679
            $this->createFolder(['eng-US' => 'P3'], $parentLocationId)->contentInfo->mainLocationId,
6680
        ];
6681
6682
        return array_values($locationService->loadLocationList($parentFoldersLocationsIds));
6683
    }
6684
6685
    /**
6686
     * Filter Locations list by hidden only.
6687
     *
6688
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
6689
     *
6690
     * @return array
6691
     */
6692
    private function filterHiddenLocations(array $locations): array
6693
    {
6694
        return array_values(
6695
            array_filter(
6696
                $locations,
6697
                function (Location $location) {
6698
                    return $location->hidden;
6699
                }
6700
            )
6701
        );
6702
    }
6703
6704
    public function testPublishVersionWithSelectedLanguages()
6705
    {
6706
        $repository = $this->getRepository();
6707
6708
        $contentService = $repository->getContentService();
6709
6710
        $publishedContent = $this->createFolder(
6711
            [
6712
                'eng-US' => 'Published US',
6713
                'ger-DE' => 'Published DE',
6714
            ],
6715
            $this->generateId('location', 2)
6716
        );
6717
6718
        $draft = $contentService->createContentDraft($publishedContent->contentInfo);
6719
        $contentUpdateStruct = new ContentUpdateStruct([
6720
            'initialLanguageCode' => 'eng-US',
6721
        ]);
6722
        $contentUpdateStruct->setField('name', 'Draft 1 US', 'eng-US');
6723
        $contentUpdateStruct->setField('name', 'Draft 1 DE', 'ger-DE');
6724
6725
        $contentService->updateContent($draft->versionInfo, $contentUpdateStruct);
6726
6727
        $contentService->publishVersion($draft->versionInfo, ['ger-DE']);
6728
        $content = $contentService->loadContent($draft->contentInfo->id);
6729
        $this->assertEquals(
6730
            [
6731
                'eng-US' => 'Published US',
6732
                'ger-DE' => 'Draft 1 DE',
6733
            ],
6734
            $content->fields['name']
6735
        );
6736
    }
6737
6738
    public function testCreateContentWithRomanianSpecialCharsInTitle()
6739
    {
6740
        $repository = $this->getRepository();
6741
6742
        $baseName = 'ȘșțȚdfdf';
6743
        $expectedPath = '/SstTdfdf';
6744
6745
        $this->createFolder(['eng-US' => $baseName], 2);
6746
6747
        $urlAliasService = $repository->getURLAliasService();
6748
        $urlAlias = $urlAliasService->lookup($expectedPath);
6749
        $this->assertSame($expectedPath, $urlAlias->path);
6750
    }
6751
}
6752