Completed
Push — version_load_race ( f933c6...4da690 )
by André
31:18 queued 14:13
created

ContentTest   F

Complexity

Total Complexity 156

Size/Duplication

Total Lines 5975
Duplicated Lines 10.08 %

Coupling/Cohesion

Components 1
Dependencies 35

Importance

Changes 0
Metric Value
dl 602
loc 5975
rs 0.8
c 0
b 0
f 0
wmc 156
lcom 1
cbo 35

100 Methods

Rating   Name   Duplication   Size   Complexity  
B testConstructor() 0 63 1
A testLoadVersionInfoById() 43 43 1
A testLoadVersionInfoByIdAndVersionNumber() 43 43 1
A testLoadVersionInfoByIdThrowsNotFoundException() 0 25 1
A testLoadVersionInfoByIdThrowsUnauthorizedExceptionNonPublishedVersion() 0 38 1
A testLoadVersionInfoByIdPublishedVersion() 40 40 1
A testLoadVersionInfoByIdNonPublishedVersion() 40 40 1
A testLoadVersionInfo() 0 23 1
A testLoadContent() 0 28 1
A testLoadContentNonPublished() 34 34 1
A testLoadContentUnauthorized() 0 20 1
A testLoadContentNotPublishedStatusUnauthorized() 34 34 1
B testInternalLoadContent() 0 42 5
A internalLoadContentProvider() 0 20 1
A testInternalLoadContentNotFound() 0 20 1
A testLoadContentByContentInfo() 0 26 1
A testLoadContentByVersionInfo() 0 30 1
A testDeleteContentThrowsUnauthorizedException() 0 24 1
B testDeleteContent() 0 55 2
A testDeleteContentWithRollback() 0 37 1
A testDeleteVersionThrowsBadStateExceptionLastVersion() 0 46 1
A testCreateContentThrowsInvalidArgumentExceptionMainLanguageCodeNotSet() 0 5 1
A testCreateContentThrowsInvalidArgumentExceptionContentTypeNotSet() 0 8 1
A testCreateContentThrowsUnauthorizedException() 0 52 1
B testCreateContentThrowsInvalidArgumentExceptionDuplicateRemoteId() 0 59 1
A mapStructFieldsForCreate() 0 20 4
B determineValuesForCreate() 12 37 6
A determineLanguageCodesForCreate() 16 16 4
B assertForTestCreateContentNonRedundantFieldSet() 0 221 3
A providerForTestCreateContentNonRedundantFieldSet1() 0 44 1
A testCreateContentNonRedundantFieldSet1() 22 22 1
B providerForTestCreateContentNonRedundantFieldSet2() 0 66 1
A testCreateContentNonRedundantFieldSet2() 0 32 1
B providerForTestCreateContentNonRedundantFieldSetComplex() 0 120 1
A fixturesForTestCreateContentNonRedundantFieldSetComplex() 0 45 1
A testCreateContentNonRedundantFieldSetComplex() 0 11 1
A providerForTestCreateContentWithInvalidLanguage() 29 29 1
B testCreateContentWithInvalidLanguage() 7 82 2
A assertForCreateContentContentValidationException() 0 52 1
A providerForTestCreateContentThrowsContentValidationExceptionFieldDefinition() 17 17 1
A testCreateContentThrowsContentValidationExceptionFieldDefinition() 0 8 1
A providerForTestCreateContentThrowsContentValidationExceptionTranslation() 17 17 1
A testCreateContentThrowsContentValidationExceptionTranslation() 21 21 1
B assertForTestCreateContentRequiredField() 0 112 1
A providerForTestCreateContentThrowsContentValidationExceptionRequiredField() 19 19 1
A testCreateContentRequiredField() 0 37 2
B assertForTestCreateContentThrowsContentFieldValidationException() 0 146 4
A providerForTestCreateContentThrowsContentFieldValidationException() 0 4 1
A testCreateContentThrowsContentFieldValidationException() 0 19 2
B testCreateContentWithLocations() 0 127 1
B testCreateContentWithLocationsDuplicateUnderParent() 0 119 1
B testCreateContentObjectStates() 0 96 1
A testCreateContentWithRollback() 0 41 1
A providerForTestUpdateContentThrowsBadStateException() 0 7 1
A testUpdateContentThrowsBadStateException() 0 30 1
A testUpdateContentThrowsUnauthorizedException() 0 39 1
A determineLanguageCodesForUpdate() 0 17 5
B mapStructFieldsForUpdate() 0 26 6
B determineValuesForUpdate() 12 46 7
A stubValues() 0 10 3
B assertForTestUpdateContentNonRedundantFieldSet() 0 237 2
A providerForTestUpdateContentNonRedundantFieldSet1() 0 52 1
A testUpdateContentNonRedundantFieldSet1() 34 34 1
B providerForTestUpdateContentNonRedundantFieldSet2() 0 167 1
A testUpdateContentNonRedundantFieldSet2() 34 34 1
B providerForTestUpdateContentNonRedundantFieldSet3() 0 216 1
A testUpdateContentNonRedundantFieldSet3() 0 52 1
B providerForTestUpdateContentNonRedundantFieldSet4() 0 241 1
A testUpdateContentNonRedundantFieldSet4() 0 52 1
B providerForTestUpdateContentNonRedundantFieldSetComplex() 0 228 1
B fixturesForTestUpdateContentNonRedundantFieldSetComplex() 0 82 1
A testUpdateContentNonRedundantFieldSetComplex() 0 12 1
A providerForTestUpdateContentWithInvalidLanguage() 29 29 1
B testUpdateContentWithInvalidLanguage() 7 69 2
B assertForUpdateContentContentValidationException() 7 83 2
A providerForTestUpdateContentThrowsContentValidationExceptionFieldDefinition() 17 17 1
A testUpdateContentThrowsContentValidationExceptionFieldDefinition() 0 8 1
A providerForTestUpdateContentThrowsContentValidationExceptionTranslation() 17 17 1
A testUpdateContentThrowsContentValidationExceptionTranslation() 21 21 1
B assertForTestUpdateContentRequiredField() 0 120 1
A providerForTestUpdateContentRequiredField() 19 19 1
A testUpdateContentRequiredField() 0 47 2
B assertForTestUpdateContentThrowsContentFieldValidationException() 0 131 1
B providerForTestUpdateContentThrowsContentFieldValidationException() 0 121 2
A testUpdateContentThrowsContentFieldValidationException() 0 18 2
A testUpdateContentTransactionRollback() 0 54 1
A testCopyContentThrowsUnauthorizedException() 0 40 1
B testCopyContent() 0 109 1
B testCopyContentWithVersionInfo() 0 109 1
B testCopyContentWithRollback() 0 63 1
A mockGetDefaultObjectStates() 0 39 1
A mockSetDefaultObjectStates() 0 19 2
B mockPublishVersion() 0 69 3
A mockPublishUrlAliasesForContent() 0 32 1
A getDomainMapperMock() 11 11 2
A getRelationProcessorMock() 0 11 2
A getNameSchemaServiceMock() 0 11 2
A getContentTypeServiceMock() 0 11 2
A getLocationServiceMock() 0 11 2
A getPartlyMockedContentService() 0 20 2

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 ContentTest 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 ContentTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * File contains: eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest 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\Core\Repository\Tests\Service\Mock;
10
11
use eZ\Publish\API\Repository\Values\Content\Language;
12
use eZ\Publish\API\Repository\Values\Content\LocationCreateStruct;
13
use eZ\Publish\Core\Base\Exceptions\ContentFieldValidationException;
14
use eZ\Publish\Core\Base\Exceptions\ContentValidationException;
15
use eZ\Publish\Core\Repository\Tests\Service\Mock\Base as BaseServiceMockTest;
16
use eZ\Publish\Core\Repository\ContentService;
17
use eZ\Publish\Core\Repository\Values\Content\Location;
18
use eZ\Publish\Core\Repository\Values\Content\Content;
19
use eZ\Publish\Core\Repository\Values\Content\ContentCreateStruct;
20
use eZ\Publish\Core\Repository\Values\Content\ContentUpdateStruct;
21
use eZ\Publish\API\Repository\Values\Content\Content as APIContent;
22
use eZ\Publish\API\Repository\Values\Content\VersionInfo as APIVersionInfo;
23
use eZ\Publish\Core\Repository\Values\Content\VersionInfo;
24
use eZ\Publish\API\Repository\Values\Content\Field;
25
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
26
use eZ\Publish\Core\Repository\Values\ContentType\ContentType;
27
use eZ\Publish\Core\Repository\Values\ContentType\FieldDefinition;
28
use eZ\Publish\SPI\Persistence\Content\Location as SPILocation;
29
use eZ\Publish\SPI\Persistence\Content as SPIContent;
30
use eZ\Publish\SPI\Persistence\Content\UpdateStruct as SPIContentUpdateStruct;
31
use eZ\Publish\SPI\Persistence\Content\CreateStruct as SPIContentCreateStruct;
32
use eZ\Publish\SPI\Persistence\Content\Field as SPIField;
33
use eZ\Publish\SPI\Persistence\Content\ObjectState\Group as SPIObjectStateGroup;
34
use eZ\Publish\SPI\Persistence\Content\ObjectState as SPIObjectState;
35
use eZ\Publish\SPI\Persistence\Content\VersionInfo as SPIVersionInfo;
36
use eZ\Publish\SPI\Persistence\Content\ContentInfo as SPIContentInfo;
37
use eZ\Publish\SPI\Persistence\Content\MetadataUpdateStruct as SPIMetadataUpdateStruct;
38
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
39
use eZ\Publish\Core\Repository\Values\User\UserReference;
40
use Exception;
41
42
/**
43
 * Mock test case for Content service.
44
 */
45
class ContentTest extends BaseServiceMockTest
46
{
47
    /**
48
     * Represents empty Field Value.
49
     */
50
    const EMPTY_FIELD_VALUE = 'empty';
51
52
    /**
53
     * Test for the __construct() method.
54
     *
55
     * @covers \eZ\Publish\Core\Repository\ContentService::__construct
56
     */
57
    public function testConstructor()
58
    {
59
        $repositoryMock = $this->getRepositoryMock();
60
        /** @var \eZ\Publish\SPI\Persistence\Handler $persistenceHandlerMock */
61
        $persistenceHandlerMock = $this->getPersistenceMockHandler('Handler');
62
        $domainMapperMock = $this->getDomainMapperMock();
63
        $relationProcessorMock = $this->getRelationProcessorMock();
64
        $nameSchemaServiceMock = $this->getNameSchemaServiceMock();
65
        $fieldTypeRegistryMock = $this->getFieldTypeRegistryMock();
66
        $settings = ['default_version_archive_limit' => 10];
67
68
        $service = new ContentService(
69
            $repositoryMock,
0 ignored issues
show
Bug introduced by
It seems like $repositoryMock defined by $this->getRepositoryMock() on line 59 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, eZ\Publish\Core\Reposito...tService::__construct() does only seem to accept object<eZ\Publish\API\Repository\Repository>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
70
            $persistenceHandlerMock,
71
            $domainMapperMock,
0 ignored issues
show
Bug introduced by
It seems like $domainMapperMock defined by $this->getDomainMapperMock() on line 62 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, eZ\Publish\Core\Reposito...tService::__construct() does only seem to accept object<eZ\Publish\Core\R...ry\Helper\DomainMapper>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
72
            $relationProcessorMock,
0 ignored issues
show
Bug introduced by
It seems like $relationProcessorMock defined by $this->getRelationProcessorMock() on line 63 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, eZ\Publish\Core\Reposito...tService::__construct() does only seem to accept object<eZ\Publish\Core\R...lper\RelationProcessor>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
73
            $nameSchemaServiceMock,
0 ignored issues
show
Bug introduced by
It seems like $nameSchemaServiceMock defined by $this->getNameSchemaServiceMock() on line 64 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, eZ\Publish\Core\Reposito...tService::__construct() does only seem to accept object<eZ\Publish\Core\R...lper\NameSchemaService>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
74
            $fieldTypeRegistryMock,
0 ignored issues
show
Bug introduced by
It seems like $fieldTypeRegistryMock defined by $this->getFieldTypeRegistryMock() on line 65 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, eZ\Publish\Core\Reposito...tService::__construct() does only seem to accept object<eZ\Publish\Core\R...lper\FieldTypeRegistry>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
75
            $settings
76
        );
77
78
        $this->assertAttributeSame(
79
            $repositoryMock,
80
            'repository',
81
            $service
82
        );
83
84
        $this->assertAttributeSame(
85
            $persistenceHandlerMock,
86
            'persistenceHandler',
87
            $service
88
        );
89
90
        $this->assertAttributeSame(
91
            $domainMapperMock,
92
            'domainMapper',
93
            $service
94
        );
95
96
        $this->assertAttributeSame(
97
            $relationProcessorMock,
98
            'relationProcessor',
99
            $service
100
        );
101
102
        $this->assertAttributeSame(
103
            $nameSchemaServiceMock,
104
            'nameSchemaService',
105
            $service
106
        );
107
108
        $this->assertAttributeSame(
109
            $fieldTypeRegistryMock,
110
            'fieldTypeRegistry',
111
            $service
112
        );
113
114
        $this->assertAttributeSame(
115
            $settings,
116
            'settings',
117
            $service
118
        );
119
    }
120
121
    /**
122
     * Test for the loadVersionInfo() method, of published version.
123
     *
124
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
125
     */
126 View Code Duplication
    public function testLoadVersionInfoById()
127
    {
128
        $repository = $this->getRepositoryMock();
129
        $contentServiceMock = $this->getPartlyMockedContentService(['loadContentInfo']);
130
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
131
        $contentHandler = $this->getPersistenceMock()->contentHandler();
132
        $domainMapperMock = $this->getDomainMapperMock();
133
        $versionInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
134
135
        $versionInfoMock->expects($this->any())
136
            ->method('__get')
137
            ->with('status')
138
            ->will($this->returnValue(APIVersionInfo::STATUS_PUBLISHED));
139
140
        $contentServiceMock->expects($this->never())
141
            ->method('loadContentInfo');
142
143
        $contentHandler->expects($this->once())
144
            ->method('loadVersionInfo')
145
            ->with(
146
                $this->equalTo(42),
147
                $this->equalTo(null)
148
            )->will(
149
                $this->returnValue(new SPIVersionInfo())
150
            );
151
152
        $domainMapperMock->expects($this->once())
153
            ->method('buildVersionInfoDomainObject')
154
            ->with(new SPIVersionInfo())
155
            ->will($this->returnValue($versionInfoMock));
156
157
        $repository->expects($this->once())
158
            ->method('canUser')
159
            ->with(
160
                $this->equalTo('content'),
161
                $this->equalTo('read'),
162
                $this->equalTo($versionInfoMock)
163
            )->will($this->returnValue(true));
164
165
        $result = $contentServiceMock->loadVersionInfoById(42);
166
167
        $this->assertEquals($versionInfoMock, $result);
168
    }
169
170
    /**
171
     * Test for the loadVersionInfo() method, of a draft.
172
     *
173
     * @depends testLoadVersionInfoById
174
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
175
     */
176 View Code Duplication
    public function testLoadVersionInfoByIdAndVersionNumber()
177
    {
178
        $repository = $this->getRepositoryMock();
179
        $contentServiceMock = $this->getPartlyMockedContentService(['loadContentInfo']);
180
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
181
        $contentHandler = $this->getPersistenceMock()->contentHandler();
182
        $domainMapperMock = $this->getDomainMapperMock();
183
        $versionInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
184
185
        $versionInfoMock->expects($this->any())
186
            ->method('__get')
187
            ->with('status')
188
            ->will($this->returnValue(APIVersionInfo::STATUS_DRAFT));
189
190
        $contentServiceMock->expects($this->never())
191
            ->method('loadContentInfo');
192
193
        $contentHandler->expects($this->once())
194
            ->method('loadVersionInfo')
195
            ->with(
196
                $this->equalTo(42),
197
                $this->equalTo(2)
198
            )->will(
199
                $this->returnValue(new SPIVersionInfo())
200
            );
201
202
        $domainMapperMock->expects($this->once())
203
            ->method('buildVersionInfoDomainObject')
204
            ->with(new SPIVersionInfo())
205
            ->will($this->returnValue($versionInfoMock));
206
207
        $repository->expects($this->once())
208
            ->method('canUser')
209
            ->with(
210
                $this->equalTo('content'),
211
                $this->equalTo('versionread'),
212
                $this->equalTo($versionInfoMock)
213
            )->will($this->returnValue(true));
214
215
        $result = $contentServiceMock->loadVersionInfoById(42, 2);
216
217
        $this->assertEquals($versionInfoMock, $result);
218
    }
219
220
    /**
221
     * Test for the loadVersionInfo() method.
222
     *
223
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
224
     * @expectedException \eZ\Publish\Core\Base\Exceptions\NotFoundException
225
     */
226
    public function testLoadVersionInfoByIdThrowsNotFoundException()
227
    {
228
        $contentServiceMock = $this->getPartlyMockedContentService(['loadContentInfo']);
229
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
230
        $contentHandler = $this->getPersistenceMock()->contentHandler();
231
232
        $contentHandler->expects($this->once())
233
            ->method('loadVersionInfo')
234
            ->with(
235
                $this->equalTo(42),
236
                $this->equalTo(24)
237
            )->will(
238
                $this->throwException(
239
                    new NotFoundException(
240
                        'Content',
241
                        [
242
                            'contentId' => 42,
243
                            'versionNo' => 24,
244
                        ]
245
                    )
246
                )
247
            );
248
249
        $contentServiceMock->loadVersionInfoById(42, 24);
250
    }
251
252
    /**
253
     * Test for the loadVersionInfo() method.
254
     *
255
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
256
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
257
     */
258
    public function testLoadVersionInfoByIdThrowsUnauthorizedExceptionNonPublishedVersion()
259
    {
260
        $repository = $this->getRepositoryMock();
261
        $contentServiceMock = $this->getPartlyMockedContentService();
262
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
263
        $contentHandler = $this->getPersistenceMock()->contentHandler();
264
        $domainMapperMock = $this->getDomainMapperMock();
265
        $versionInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
266
267
        $versionInfoMock->expects($this->any())
268
            ->method('__get')
269
            ->with('status')
270
            ->will($this->returnValue(APIVersionInfo::STATUS_DRAFT));
271
272
        $contentHandler->expects($this->once())
273
            ->method('loadVersionInfo')
274
            ->with(
275
                $this->equalTo(42),
276
                $this->equalTo(24)
277
            )->will(
278
                $this->returnValue(new SPIVersionInfo())
279
            );
280
281
        $domainMapperMock->expects($this->once())
282
            ->method('buildVersionInfoDomainObject')
283
            ->with(new SPIVersionInfo())
284
            ->will($this->returnValue($versionInfoMock));
285
286
        $repository->expects($this->once())
287
            ->method('canUser')
288
            ->with(
289
                $this->equalTo('content'),
290
                $this->equalTo('versionread'),
291
                $this->equalTo($versionInfoMock)
292
            )->will($this->returnValue(false));
293
294
        $contentServiceMock->loadVersionInfoById(42, 24);
295
    }
296
297
    /**
298
     * Test for the loadVersionInfo() method.
299
     *
300
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
301
     */
302 View Code Duplication
    public function testLoadVersionInfoByIdPublishedVersion()
303
    {
304
        $repository = $this->getRepositoryMock();
305
        $contentServiceMock = $this->getPartlyMockedContentService();
306
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
307
        $contentHandler = $this->getPersistenceMock()->contentHandler();
308
        $domainMapperMock = $this->getDomainMapperMock();
309
        $versionInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
310
311
        $versionInfoMock->expects($this->any())
312
            ->method('__get')
313
            ->with('status')
314
            ->will($this->returnValue(APIVersionInfo::STATUS_PUBLISHED));
315
316
        $contentHandler->expects($this->once())
317
            ->method('loadVersionInfo')
318
            ->with(
319
                $this->equalTo(42),
320
                $this->equalTo(24)
321
            )->will(
322
                $this->returnValue(new SPIVersionInfo())
323
            );
324
325
        $domainMapperMock->expects($this->once())
326
            ->method('buildVersionInfoDomainObject')
327
            ->with(new SPIVersionInfo())
328
            ->will($this->returnValue($versionInfoMock));
329
330
        $repository->expects($this->once())
331
            ->method('canUser')
332
            ->with(
333
                $this->equalTo('content'),
334
                $this->equalTo('read'),
335
                $this->equalTo($versionInfoMock)
336
            )->will($this->returnValue(true));
337
338
        $result = $contentServiceMock->loadVersionInfoById(42, 24);
339
340
        $this->assertEquals($versionInfoMock, $result);
341
    }
342
343
    /**
344
     * Test for the loadVersionInfo() method.
345
     *
346
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
347
     */
348 View Code Duplication
    public function testLoadVersionInfoByIdNonPublishedVersion()
349
    {
350
        $repository = $this->getRepositoryMock();
351
        $contentServiceMock = $this->getPartlyMockedContentService();
352
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
353
        $contentHandler = $this->getPersistenceMock()->contentHandler();
354
        $domainMapperMock = $this->getDomainMapperMock();
355
        $versionInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
356
357
        $versionInfoMock->expects($this->any())
358
            ->method('__get')
359
            ->with('status')
360
            ->will($this->returnValue(APIVersionInfo::STATUS_DRAFT));
361
362
        $contentHandler->expects($this->once())
363
            ->method('loadVersionInfo')
364
            ->with(
365
                $this->equalTo(42),
366
                $this->equalTo(24)
367
            )->will(
368
                $this->returnValue(new SPIVersionInfo())
369
            );
370
371
        $domainMapperMock->expects($this->once())
372
            ->method('buildVersionInfoDomainObject')
373
            ->with(new SPIVersionInfo())
374
            ->will($this->returnValue($versionInfoMock));
375
376
        $repository->expects($this->once())
377
            ->method('canUser')
378
            ->with(
379
                $this->equalTo('content'),
380
                $this->equalTo('versionread'),
381
                $this->equalTo($versionInfoMock)
382
            )->will($this->returnValue(true));
383
384
        $result = $contentServiceMock->loadVersionInfoById(42, 24);
385
386
        $this->assertEquals($versionInfoMock, $result);
387
    }
388
389
    /**
390
     * Test for the loadVersionInfo() method.
391
     *
392
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfo
393
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoById
394
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoByIdThrowsNotFoundException
395
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoByIdThrowsUnauthorizedExceptionNonPublishedVersion
396
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoByIdPublishedVersion
397
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoByIdNonPublishedVersion
398
     */
399
    public function testLoadVersionInfo()
400
    {
401
        $contentServiceMock = $this->getPartlyMockedContentService(
402
            ['loadVersionInfoById']
403
        );
404
        $contentServiceMock->expects(
405
            $this->once()
406
        )->method(
407
            'loadVersionInfoById'
408
        )->with(
409
            $this->equalTo(42),
410
            $this->equalTo(7)
411
        )->will(
412
            $this->returnValue('result')
413
        );
414
415
        $result = $contentServiceMock->loadVersionInfo(
416
            new ContentInfo(['id' => 42]),
417
            7
418
        );
419
420
        $this->assertEquals('result', $result);
421
    }
422
423
    public function testLoadContent()
424
    {
425
        $repository = $this->getRepositoryMock();
426
        $contentService = $this->getPartlyMockedContentService(['internalLoadContent']);
427
        $content = $this->getMock('eZ\Publish\API\Repository\Values\Content\Content');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
428
        $versionInfo = $this
429
            ->getMockBuilder('eZ\Publish\API\Repository\Values\Content\VersionInfo')
430
            ->setConstructorArgs([['status' => APIVersionInfo::STATUS_PUBLISHED]])
431
            ->getMockForAbstractClass();
432
        $content
433
            ->expects($this->once())
434
            ->method('getVersionInfo')
435
            ->will($this->returnValue($versionInfo));
436
        $contentId = 123;
437
        $contentService
438
            ->expects($this->once())
439
            ->method('internalLoadContent')
440
            ->with($contentId)
441
            ->will($this->returnValue($content));
442
443
        $repository
444
            ->expects($this->once())
445
            ->method('canUser')
446
            ->with('content', 'read', $content)
447
            ->will($this->returnValue(true));
448
449
        $this->assertSame($content, $contentService->loadContent($contentId));
450
    }
451
452 View Code Duplication
    public function testLoadContentNonPublished()
453
    {
454
        $repository = $this->getRepositoryMock();
455
        $contentService = $this->getPartlyMockedContentService(['internalLoadContent']);
456
        $content = $this->getMock('eZ\Publish\API\Repository\Values\Content\Content');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
457
        $versionInfo = $this
458
            ->getMockBuilder('eZ\Publish\API\Repository\Values\Content\VersionInfo')
459
            ->setConstructorArgs([['status' => APIVersionInfo::STATUS_DRAFT]])
460
            ->getMockForAbstractClass();
461
        $content
462
            ->expects($this->once())
463
            ->method('getVersionInfo')
464
            ->will($this->returnValue($versionInfo));
465
        $contentId = 123;
466
        $contentService
467
            ->expects($this->once())
468
            ->method('internalLoadContent')
469
            ->with($contentId)
470
            ->will($this->returnValue($content));
471
472
        $repository
473
            ->expects($this->exactly(2))
474
            ->method('canUser')
475
            ->will(
476
                $this->returnValueMap(
477
                    [
478
                        ['content', 'read', $content, null, true],
479
                        ['content', 'versionread', $content, null, true],
480
                    ]
481
                )
482
            );
483
484
        $this->assertSame($content, $contentService->loadContent($contentId));
485
    }
486
487
    /**
488
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
489
     */
490
    public function testLoadContentUnauthorized()
491
    {
492
        $repository = $this->getRepositoryMock();
493
        $contentService = $this->getPartlyMockedContentService(['internalLoadContent']);
494
        $content = $this->getMock('eZ\Publish\API\Repository\Values\Content\Content');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
495
        $contentId = 123;
496
        $contentService
497
            ->expects($this->once())
498
            ->method('internalLoadContent')
499
            ->with($contentId)
500
            ->will($this->returnValue($content));
501
502
        $repository
503
            ->expects($this->once())
504
            ->method('canUser')
505
            ->with('content', 'read', $content)
506
            ->will($this->returnValue(false));
507
508
        $contentService->loadContent($contentId);
509
    }
510
511
    /**
512
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
513
     */
514 View Code Duplication
    public function testLoadContentNotPublishedStatusUnauthorized()
515
    {
516
        $repository = $this->getRepositoryMock();
517
        $contentService = $this->getPartlyMockedContentService(['internalLoadContent']);
518
        $content = $this->getMock('eZ\Publish\API\Repository\Values\Content\Content');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
519
        $versionInfo = $this
520
            ->getMockBuilder('eZ\Publish\API\Repository\Values\Content\VersionInfo')
521
            ->setConstructorArgs([['status' => APIVersionInfo::STATUS_DRAFT]])
522
            ->getMockForAbstractClass();
523
        $content
524
            ->expects($this->once())
525
            ->method('getVersionInfo')
526
            ->will($this->returnValue($versionInfo));
527
        $contentId = 123;
528
        $contentService
529
            ->expects($this->once())
530
            ->method('internalLoadContent')
531
            ->with($contentId)
532
            ->will($this->returnValue($content));
533
534
        $repository
535
            ->expects($this->exactly(2))
536
            ->method('canUser')
537
            ->will(
538
                $this->returnValueMap(
539
                    [
540
                        ['content', 'read', $content, null, true],
541
                        ['content', 'versionread', $content, null, false],
542
                    ]
543
                )
544
            );
545
546
        $contentService->loadContent($contentId);
547
    }
548
549
    /**
550
     * @dataProvider internalLoadContentProvider
551
     */
552
    public function testInternalLoadContent($id, $languages, $versionNo, $isRemoteId, $useAlwaysAvailable)
553
    {
554
        $contentService = $this->getPartlyMockedContentService();
555
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
556
        $contentHandler = $this->getPersistenceMock()->contentHandler();
557
        $realId = $id;
558
559
        if ($isRemoteId) {
560
            $realId = 123;
561
            $spiContentInfo = new SPIContentInfo(['currentVersionNo' => $versionNo ?: 7, 'id' => $realId]);
562
            $contentHandler
563
                ->expects($this->once())
564
                ->method('loadContentInfoByRemoteId')
565
                ->with($id)
566
                ->will($this->returnValue($spiContentInfo));
567
        } elseif (!empty($languages) && $useAlwaysAvailable) {
568
            $spiContentInfo = new SPIContentInfo(['alwaysAvailable' => false]);
569
            $contentHandler
570
                ->expects($this->once())
571
                ->method('loadContentInfo')
572
                ->with($id)
573
                ->will($this->returnValue($spiContentInfo));
574
        }
575
576
        $spiContent = new SPIContent();
577
        $contentHandler
578
            ->expects($this->once())
579
            ->method('load')
580
            ->with($realId, $versionNo, $languages)
581
            ->will($this->returnValue($spiContent));
582
        $content = $this->getMock('eZ\Publish\API\Repository\Values\Content\Content');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
583
        $this->getDomainMapperMock()
584
            ->expects($this->once())
585
            ->method('buildContentDomainObject')
586
            ->with($spiContent)
587
            ->will($this->returnValue($content));
588
589
        $this->assertSame(
590
            $content,
591
            $contentService->internalLoadContent($id, $languages, $versionNo, $isRemoteId, $useAlwaysAvailable)
592
        );
593
    }
594
595
    public function internalLoadContentProvider()
596
    {
597
        return [
598
            [123, null, null, false, false],
599
            [123, null, 456, false, false],
600
            [456, null, 123, false, true],
601
            [456, null, 2, false, false],
602
            [456, ['eng-GB'], 2, false, true],
603
            [456, ['eng-GB', 'fre-FR'], null, false, false],
604
            [456, ['eng-GB', 'fre-FR', 'nor-NO'], 2, false, false],
605
            // With remoteId
606
            [123, null, null, true, false],
607
            ['someRemoteId', null, 456, true, false],
608
            [456, null, 123, true, false],
609
            ['someRemoteId', null, 2, true, false],
610
            ['someRemoteId', ['eng-GB'], 2, true, false],
611
            [456, ['eng-GB', 'fre-FR'], null, true, false],
612
            ['someRemoteId', ['eng-GB', 'fre-FR', 'nor-NO'], 2, true, false],
613
        ];
614
    }
615
616
    /**
617
     * @expectedException \eZ\Publish\Core\Base\Exceptions\NotFoundException
618
     */
619
    public function testInternalLoadContentNotFound()
620
    {
621
        $contentService = $this->getPartlyMockedContentService();
622
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
623
        $contentHandler = $this->getPersistenceMock()->contentHandler();
624
        $id = 123;
625
        $versionNo = 7;
626
        $languages = null;
627
        $contentHandler
628
            ->expects($this->once())
629
            ->method('load')
630
            ->with($id, $versionNo, $languages)
631
            ->will(
632
                $this->throwException(
633
                    $this->getMock('eZ\Publish\API\Repository\Exceptions\NotFoundException')
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
634
                )
635
            );
636
637
        $contentService->internalLoadContent($id, $languages, $versionNo);
638
    }
639
640
    /**
641
     * Test for the loadContentByContentInfo() method.
642
     *
643
     * @covers \eZ\Publish\Core\Repository\ContentService::loadContentByContentInfo
644
     */
645
    public function testLoadContentByContentInfo()
646
    {
647
        $contentServiceMock = $this->getPartlyMockedContentService(
648
            ['loadContent']
649
        );
650
        $contentServiceMock->expects(
651
            $this->once()
652
        )->method(
653
            'loadContent'
654
        )->with(
655
            $this->equalTo(42),
656
            $this->equalTo(['cro-HR']),
657
            $this->equalTo(7),
658
            $this->equalTo(false)
659
        )->will(
660
            $this->returnValue('result')
661
        );
662
663
        $result = $contentServiceMock->loadContentByContentInfo(
664
            new ContentInfo(['id' => 42]),
665
            ['cro-HR'],
666
            7
667
        );
668
669
        $this->assertEquals('result', $result);
670
    }
671
672
    /**
673
     * Test for the loadContentByVersionInfo() method.
674
     *
675
     * @covers \eZ\Publish\Core\Repository\ContentService::loadContentByVersionInfo
676
     */
677
    public function testLoadContentByVersionInfo()
678
    {
679
        $contentServiceMock = $this->getPartlyMockedContentService(
680
            ['loadContent']
681
        );
682
        $contentServiceMock->expects(
683
            $this->once()
684
        )->method(
685
            'loadContent'
686
        )->with(
687
            $this->equalTo(42),
688
            $this->equalTo(['cro-HR']),
689
            $this->equalTo(7),
690
            $this->equalTo(false)
691
        )->will(
692
            $this->returnValue('result')
693
        );
694
695
        $result = $contentServiceMock->loadContentByVersionInfo(
696
            new VersionInfo(
697
                [
698
                    'contentInfo' => new ContentInfo(['id' => 42]),
699
                    'versionNo' => 7,
700
                ]
701
            ),
702
            ['cro-HR']
703
        );
704
705
        $this->assertEquals('result', $result);
706
    }
707
708
    /**
709
     * Test for the deleteContent() method.
710
     *
711
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteContent
712
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
713
     */
714
    public function testDeleteContentThrowsUnauthorizedException()
715
    {
716
        $repository = $this->getRepositoryMock();
717
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo']);
718
        $contentInfo = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
719
720
        $contentInfo->expects($this->any())
721
            ->method('__get')
722
            ->with('id')
723
            ->will($this->returnValue(42));
724
725
        $contentService->expects($this->once())
726
            ->method('internalLoadContentInfo')
727
            ->with(42)
728
            ->will($this->returnValue($contentInfo));
729
730
        $repository->expects($this->once())
731
            ->method('canUser')
732
            ->with('content', 'remove')
733
            ->will($this->returnValue(false));
734
735
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */
736
        $contentService->deleteContent($contentInfo);
737
    }
738
739
    /**
740
     * Test for the deleteContent() method.
741
     *
742
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteContent
743
     */
744
    public function testDeleteContent()
745
    {
746
        $repository = $this->getRepositoryMock();
747
748
        $repository->expects($this->once())
749
            ->method('canUser')
750
            ->with('content', 'remove')
751
            ->will($this->returnValue(true));
752
753
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo']);
754
        /** @var \PHPUnit_Framework_MockObject_MockObject $urlAliasHandler */
755
        $urlAliasHandler = $this->getPersistenceMock()->urlAliasHandler();
756
        /** @var \PHPUnit_Framework_MockObject_MockObject $locationHandler */
757
        $locationHandler = $this->getPersistenceMock()->locationHandler();
758
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
759
        $contentHandler = $this->getPersistenceMock()->contentHandler();
760
761
        $contentInfo = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
762
763
        $contentService->expects($this->once())
764
            ->method('internalLoadContentInfo')
765
            ->with(42)
766
            ->will($this->returnValue($contentInfo));
767
768
        $contentInfo->expects($this->any())
769
            ->method('__get')
770
            ->with('id')
771
            ->will($this->returnValue(42));
772
773
        $repository->expects($this->once())->method('beginTransaction');
774
775
        $spiLocations = [
776
            new SPILocation(['id' => 1]),
777
            new SPILocation(['id' => 2]),
778
        ];
779
        $locationHandler->expects($this->once())
780
            ->method('loadLocationsByContent')
781
            ->with(42)
782
            ->will($this->returnValue($spiLocations));
783
784
        $contentHandler->expects($this->once())
785
            ->method('deleteContent')
786
            ->with(42);
787
788
        foreach ($spiLocations as $index => $spiLocation) {
789
            $urlAliasHandler->expects($this->at($index))
790
                ->method('locationDeleted')
791
                ->with($spiLocation->id);
792
        }
793
794
        $repository->expects($this->once())->method('commit');
795
796
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */
797
        $contentService->deleteContent($contentInfo);
798
    }
799
800
    /**
801
     * Test for the deleteContent() method.
802
     *
803
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteContent
804
     * @expectedException \Exception
805
     */
806
    public function testDeleteContentWithRollback()
807
    {
808
        $repository = $this->getRepositoryMock();
809
810
        $repository->expects($this->once())
811
            ->method('canUser')
812
            ->with('content', 'remove')
813
            ->will($this->returnValue(true));
814
815
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo']);
816
        /** @var \PHPUnit_Framework_MockObject_MockObject $locationHandler */
817
        $locationHandler = $this->getPersistenceMock()->locationHandler();
818
819
        $contentInfo = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
820
821
        $contentService->expects($this->once())
822
            ->method('internalLoadContentInfo')
823
            ->with(42)
824
            ->will($this->returnValue($contentInfo));
825
826
        $contentInfo->expects($this->any())
827
            ->method('__get')
828
            ->with('id')
829
            ->will($this->returnValue(42));
830
831
        $repository->expects($this->once())->method('beginTransaction');
832
833
        $locationHandler->expects($this->once())
834
            ->method('loadLocationsByContent')
835
            ->with(42)
836
            ->will($this->throwException(new \Exception()));
837
838
        $repository->expects($this->once())->method('rollback');
839
840
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */
841
        $contentService->deleteContent($contentInfo);
842
    }
843
844
    /**
845
     * Test for the deleteVersion() method.
846
     *
847
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteVersion
848
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
849
     */
850
    public function testDeleteVersionThrowsBadStateExceptionLastVersion()
851
    {
852
        $repository = $this->getRepositoryMock();
853
        $repository
854
            ->expects($this->once())
855
            ->method('canUser')
856
            ->with('content', 'versionremove')
857
            ->will($this->returnValue(true));
858
        $repository
859
            ->expects($this->never())
860
            ->method('beginTransaction');
861
862
        $contentService = $this->getPartlyMockedContentService();
863
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
864
        $contentHandler = $this->getPersistenceMock()->contentHandler();
865
        $contentInfo = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
866
        $versionInfo = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
867
868
        $contentInfo
869
            ->expects($this->any())
870
            ->method('__get')
871
            ->with('id')
872
            ->will($this->returnValue(42));
873
874
        $versionInfo
875
            ->expects($this->any())
876
            ->method('__get')
877
            ->will(
878
                $this->returnValueMap(
879
                    [
880
                        ['versionNo', 123],
881
                        ['status', VersionInfo::STATUS_DRAFT],
882
                        ['contentInfo', $contentInfo],
883
                    ]
884
                )
885
            );
886
887
        $contentHandler
888
            ->expects($this->once())
889
            ->method('listVersions')
890
            ->with(42)
891
            ->will($this->returnValue(['version']));
892
893
        /* @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo */
894
        $contentService->deleteVersion($versionInfo);
895
    }
896
897
    /**
898
     * Test for the createContent() method.
899
     *
900
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
901
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
902
     * @expectedExceptionMessage Argument '$contentCreateStruct' is invalid: 'mainLanguageCode' property must be set
903
     */
904
    public function testCreateContentThrowsInvalidArgumentExceptionMainLanguageCodeNotSet()
905
    {
906
        $mockedService = $this->getPartlyMockedContentService();
907
        $mockedService->createContent(new ContentCreateStruct(), []);
908
    }
909
910
    /**
911
     * Test for the createContent() method.
912
     *
913
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
914
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
915
     * @expectedExceptionMessage Argument '$contentCreateStruct' is invalid: 'contentType' property must be set
916
     */
917
    public function testCreateContentThrowsInvalidArgumentExceptionContentTypeNotSet()
918
    {
919
        $mockedService = $this->getPartlyMockedContentService();
920
        $mockedService->createContent(
921
            new ContentCreateStruct(['mainLanguageCode' => 'eng-US']),
922
            []
923
        );
924
    }
925
926
    /**
927
     * Test for the createContent() method.
928
     *
929
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
930
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
931
     */
932
    public function testCreateContentThrowsUnauthorizedException()
933
    {
934
        $repositoryMock = $this->getRepositoryMock();
935
        $mockedService = $this->getPartlyMockedContentService();
936
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
937
        $contentType = new ContentType(
938
            [
939
                'id' => 123,
940
                'fieldDefinitions' => [],
941
            ]
942
        );
943
        $contentCreateStruct = new ContentCreateStruct(
944
            [
945
                'ownerId' => 169,
946
                'alwaysAvailable' => false,
947
                'mainLanguageCode' => 'eng-US',
948
                'contentType' => $contentType,
949
            ]
950
        );
951
952
        $repositoryMock->expects($this->once())
953
            ->method('getCurrentUserReference')
954
            ->will($this->returnValue(new UserReference(169)));
955
956
        $contentTypeServiceMock->expects($this->once())
957
            ->method('loadContentType')
958
            ->with($this->equalTo(123))
959
            ->will($this->returnValue($contentType));
960
961
        $repositoryMock->expects($this->once())
962
            ->method('getContentTypeService')
963
            ->will($this->returnValue($contentTypeServiceMock));
964
965
        $repositoryMock->expects($this->once())
966
            ->method('canUser')
967
            ->with(
968
                $this->equalTo('content'),
969
                $this->equalTo('create'),
970
                $this->isInstanceOf($contentCreateStruct),
971
                $this->equalTo([])
972
            )->will($this->returnValue(false));
973
974
        $mockedService->createContent(
975
            new ContentCreateStruct(
976
                [
977
                    'mainLanguageCode' => 'eng-US',
978
                    'contentType' => $contentType,
979
                ]
980
            ),
981
            []
982
        );
983
    }
984
985
    /**
986
     * Test for the createContent() method.
987
     *
988
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
989
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
990
     * @exceptionMessage Argument '$contentCreateStruct' is invalid: Another content with remoteId 'faraday' exists
991
     */
992
    public function testCreateContentThrowsInvalidArgumentExceptionDuplicateRemoteId()
993
    {
994
        $repositoryMock = $this->getRepositoryMock();
995
        $mockedService = $this->getPartlyMockedContentService(['loadContentByRemoteId']);
996
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
997
        $contentType = new ContentType(
998
            [
999
                'id' => 123,
1000
                'fieldDefinitions' => [],
1001
            ]
1002
        );
1003
        $contentCreateStruct = new ContentCreateStruct(
1004
            [
1005
                'ownerId' => 169,
1006
                'alwaysAvailable' => false,
1007
                'remoteId' => 'faraday',
1008
                'mainLanguageCode' => 'eng-US',
1009
                'contentType' => $contentType,
1010
            ]
1011
        );
1012
1013
        $repositoryMock->expects($this->once())
1014
            ->method('getCurrentUserReference')
1015
            ->will($this->returnValue(new UserReference(169)));
1016
1017
        $contentTypeServiceMock->expects($this->once())
1018
            ->method('loadContentType')
1019
            ->with($this->equalTo(123))
1020
            ->will($this->returnValue($contentType));
1021
1022
        $repositoryMock->expects($this->once())
1023
            ->method('getContentTypeService')
1024
            ->will($this->returnValue($contentTypeServiceMock));
1025
1026
        $repositoryMock->expects($this->once())
1027
            ->method('canUser')
1028
            ->with(
1029
                $this->equalTo('content'),
1030
                $this->equalTo('create'),
1031
                $this->isInstanceOf($contentCreateStruct),
1032
                $this->equalTo([])
1033
            )->will($this->returnValue(true));
1034
1035
        $mockedService->expects($this->once())
1036
            ->method('loadContentByRemoteId')
1037
            ->with($contentCreateStruct->remoteId)
1038
            ->will($this->returnValue('Hello...'));
1039
1040
        $mockedService->createContent(
1041
            new ContentCreateStruct(
1042
                [
1043
                    'remoteId' => 'faraday',
1044
                    'mainLanguageCode' => 'eng-US',
1045
                    'contentType' => $contentType,
1046
                ]
1047
            ),
1048
            []
1049
        );
1050
    }
1051
1052
    /**
1053
     * @param string $mainLanguageCode
1054
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
1055
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
1056
     *
1057
     * @return array
1058
     */
1059
    protected function mapStructFieldsForCreate($mainLanguageCode, $structFields, $fieldDefinitions)
1060
    {
1061
        $mappedFieldDefinitions = [];
1062
        foreach ($fieldDefinitions as $fieldDefinition) {
1063
            $mappedFieldDefinitions[$fieldDefinition->identifier] = $fieldDefinition;
1064
        }
1065
1066
        $mappedStructFields = [];
1067
        foreach ($structFields as $structField) {
1068
            if ($structField->languageCode === null) {
1069
                $languageCode = $mainLanguageCode;
1070
            } else {
1071
                $languageCode = $structField->languageCode;
1072
            }
1073
1074
            $mappedStructFields[$structField->fieldDefIdentifier][$languageCode] = (string)$structField->value;
1075
        }
1076
1077
        return $mappedStructFields;
1078
    }
1079
1080
    /**
1081
     * Returns full, possibly redundant array of field values, indexed by field definition
1082
     * identifier and language code.
1083
     *
1084
     * @throws \RuntimeException Method is intended to be used only with consistent fixtures
1085
     *
1086
     * @param string $mainLanguageCode
1087
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
1088
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
1089
     * @param array $languageCodes
1090
     *
1091
     * @return array
1092
     */
1093
    protected function determineValuesForCreate(
1094
        $mainLanguageCode,
1095
        array $structFields,
1096
        array $fieldDefinitions,
1097
        array $languageCodes
1098
    ) {
1099
        $mappedStructFields = $this->mapStructFieldsForCreate(
1100
            $mainLanguageCode,
1101
            $structFields,
1102
            $fieldDefinitions
1103
        );
1104
1105
        $values = [];
1106
1107
        foreach ($fieldDefinitions as $fieldDefinition) {
1108
            $identifier = $fieldDefinition->identifier;
1109
            foreach ($languageCodes as $languageCode) {
1110 View Code Duplication
                if (!$fieldDefinition->isTranslatable) {
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...
1111
                    if (isset($mappedStructFields[$identifier][$mainLanguageCode])) {
1112
                        $values[$identifier][$languageCode] = $mappedStructFields[$identifier][$mainLanguageCode];
1113
                    } else {
1114
                        $values[$identifier][$languageCode] = (string)$fieldDefinition->defaultValue;
1115
                    }
1116
                    continue;
1117
                }
1118
1119 View Code Duplication
                if (isset($mappedStructFields[$identifier][$languageCode])) {
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...
1120
                    $values[$identifier][$languageCode] = $mappedStructFields[$identifier][$languageCode];
1121
                    continue;
1122
                }
1123
1124
                $values[$identifier][$languageCode] = (string)$fieldDefinition->defaultValue;
1125
            }
1126
        }
1127
1128
        return $this->stubValues($values);
1129
    }
1130
1131
    /**
1132
     * @param string $mainLanguageCode
1133
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
1134
     *
1135
     * @return string[]
1136
     */
1137 View Code Duplication
    protected function determineLanguageCodesForCreate($mainLanguageCode, array $structFields)
1138
    {
1139
        $languageCodes = [];
1140
1141
        foreach ($structFields as $field) {
1142
            if ($field->languageCode === null || isset($languageCodes[$field->languageCode])) {
1143
                continue;
1144
            }
1145
1146
            $languageCodes[$field->languageCode] = true;
1147
        }
1148
1149
        $languageCodes[$mainLanguageCode] = true;
1150
1151
        return array_keys($languageCodes);
1152
    }
1153
1154
    /**
1155
     * Asserts that calling createContent() with given API field set causes calling
1156
     * Handler::createContent() with given SPI field set.
1157
     *
1158
     * @param string $mainLanguageCode
1159
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
1160
     * @param \eZ\Publish\SPI\Persistence\Content\Field[] $spiFields
1161
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
1162
     * @param \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct[] $locationCreateStructs
1163
     * @param \eZ\Publish\SPI\Persistence\Content\ObjectState\Group[] $objectStateGroups
0 ignored issues
show
Bug introduced by
There is no parameter named $objectStateGroups. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1164
     * @param bool $execute
1165
     *
1166
     * @return mixed
1167
     */
1168
    protected function assertForTestCreateContentNonRedundantFieldSet(
1169
        $mainLanguageCode,
1170
        array $structFields,
1171
        array $spiFields,
1172
        array $fieldDefinitions,
1173
        array $locationCreateStructs = [],
1174
        $withObjectStates = false,
1175
        $execute = true
1176
    ) {
1177
        $repositoryMock = $this->getRepositoryMock();
1178
        $mockedService = $this->getPartlyMockedContentService();
1179
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
1180
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
1181
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
1182
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
1183
        /** @var \PHPUnit_Framework_MockObject_MockObject $objectStateHandlerMock */
1184
        $objectStateHandlerMock = $this->getPersistenceMock()->objectStateHandler();
1185
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
1186
        $fieldTypeServiceMock = $this->getFieldTypeServiceMock();
0 ignored issues
show
Unused Code introduced by
$fieldTypeServiceMock 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...
1187
        $domainMapperMock = $this->getDomainMapperMock();
1188
        $relationProcessorMock = $this->getRelationProcessorMock();
1189
        $nameSchemaServiceMock = $this->getNameSchemaServiceMock();
1190
        $fieldTypeMock = $this->getMock('eZ\\Publish\\SPI\\FieldType\\FieldType');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
1191
        $languageCodes = $this->determineLanguageCodesForCreate($mainLanguageCode, $structFields);
1192
        $contentType = new ContentType(
1193
            [
1194
                'id' => 123,
1195
                'fieldDefinitions' => $fieldDefinitions,
1196
                'nameSchema' => '<nameSchema>',
1197
            ]
1198
        );
1199
        $contentCreateStruct = new ContentCreateStruct(
1200
            [
1201
                'fields' => $structFields,
1202
                'mainLanguageCode' => $mainLanguageCode,
1203
                'contentType' => $contentType,
1204
                'alwaysAvailable' => false,
1205
                'ownerId' => 169,
1206
                'sectionId' => 1,
1207
            ]
1208
        );
1209
1210
        $languageHandlerMock->expects($this->any())
1211
            ->method('loadByLanguageCode')
1212
            ->with($this->isType('string'))
1213
            ->will(
1214
                $this->returnCallback(
1215
                    function () {
1216
                        return new Language(['id' => 4242]);
1217
                    }
1218
                )
1219
            );
1220
1221
        $repositoryMock->expects($this->once())->method('beginTransaction');
1222
1223
        $contentTypeServiceMock->expects($this->once())
1224
            ->method('loadContentType')
1225
            ->with($this->equalTo($contentType->id))
1226
            ->will($this->returnValue($contentType));
1227
1228
        $repositoryMock->expects($this->once())
1229
            ->method('getContentTypeService')
1230
            ->will($this->returnValue($contentTypeServiceMock));
1231
1232
        $that = $this;
1233
        $repositoryMock->expects($this->once())
1234
            ->method('canUser')
1235
            ->with(
1236
                $this->equalTo('content'),
1237
                $this->equalTo('create'),
1238
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
1239
                $this->equalTo($locationCreateStructs)
1240
            )->will(
1241
                $this->returnCallback(
1242
                    function () use ($that, $contentCreateStruct) {
1243
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
1244
1245
                        return true;
1246
                    }
1247
                )
1248
            );
1249
1250
        $domainMapperMock->expects($this->once())
1251
            ->method('getUniqueHash')
1252
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
1253
            ->will(
1254
                $this->returnCallback(
1255
                    function ($object) use ($that, $contentCreateStruct) {
1256
                        $that->assertEquals($contentCreateStruct, $object);
1257
1258
                        return 'hash';
1259
                    }
1260
                )
1261
            );
1262
1263
        $fieldTypeMock->expects($this->any())
1264
            ->method('acceptValue')
1265
            ->will(
1266
                $this->returnCallback(
1267
                    function ($valueString) {
1268
                        return new ValueStub($valueString);
1269
                    }
1270
                )
1271
            );
1272
1273
        $fieldTypeMock->expects($this->any())
1274
            ->method('toPersistenceValue')
1275
            ->will(
1276
                $this->returnCallback(
1277
                    function (ValueStub $value) {
1278
                        return (string)$value;
1279
                    }
1280
                )
1281
            );
1282
1283
        $emptyValue = self::EMPTY_FIELD_VALUE;
1284
        $fieldTypeMock->expects($this->any())
1285
            ->method('isEmptyValue')
1286
            ->will(
1287
                $this->returnCallback(
1288
                    function (ValueStub $value) use ($emptyValue) {
1289
                        return $emptyValue === (string)$value;
1290
                    }
1291
                )
1292
            );
1293
1294
        $fieldTypeMock->expects($this->any())
1295
            ->method('validate')
1296
            ->will($this->returnValue([]));
1297
1298
        $this->getFieldTypeRegistryMock()->expects($this->any())
1299
            ->method('getFieldType')
1300
            ->will($this->returnValue($fieldTypeMock));
1301
1302
        $relationProcessorMock
1303
            ->expects($this->exactly(count($fieldDefinitions) * count($languageCodes)))
1304
            ->method('appendFieldRelations')
1305
            ->with(
1306
                $this->isType('array'),
1307
                $this->isType('array'),
1308
                $this->isInstanceOf('eZ\\Publish\\SPI\\FieldType\\FieldType'),
1309
                $this->isInstanceOf('eZ\\Publish\\Core\\FieldType\\Value'),
1310
                $this->anything()
1311
            );
1312
1313
        $values = $this->determineValuesForCreate(
1314
            $mainLanguageCode,
1315
            $structFields,
1316
            $fieldDefinitions,
1317
            $languageCodes
1318
        );
1319
        $nameSchemaServiceMock->expects($this->once())
1320
            ->method('resolve')
1321
            ->with(
1322
                $this->equalTo($contentType->nameSchema),
1323
                $this->equalTo($contentType),
1324
                $this->equalTo($values),
1325
                $this->equalTo($languageCodes)
1326
            )->will($this->returnValue([]));
1327
1328
        $relationProcessorMock->expects($this->any())
1329
            ->method('processFieldRelations')
1330
            ->with(
1331
                $this->isType('array'),
1332
                $this->equalTo(42),
1333
                $this->isType('int'),
1334
                $this->equalTo($contentType),
1335
                $this->equalTo([])
1336
            );
1337
1338
        if (!$withObjectStates) {
1339
            $objectStateHandlerMock->expects($this->once())
1340
                ->method('loadAllGroups')
1341
                ->will($this->returnValue([]));
1342
        }
1343
1344
        if ($execute) {
1345
            $spiContentCreateStruct = new SPIContentCreateStruct(
1346
                [
1347
                    'name' => [],
1348
                    'typeId' => 123,
1349
                    'sectionId' => 1,
1350
                    'ownerId' => 169,
1351
                    'remoteId' => 'hash',
1352
                    'fields' => $spiFields,
1353
                    'modified' => time(),
1354
                    'initialLanguageId' => 4242,
1355
                ]
1356
            );
1357
            $spiContentCreateStruct2 = clone $spiContentCreateStruct;
1358
            ++$spiContentCreateStruct2->modified;
1359
1360
            $spiContent = new SPIContent(
1361
                [
1362
                    'versionInfo' => new SPIContent\VersionInfo(
1363
                        [
1364
                            'contentInfo' => new SPIContent\ContentInfo(['id' => 42]),
1365
                            'versionNo' => 7,
1366
                        ]
1367
                    ),
1368
                ]
1369
            );
1370
1371
            $contentHandlerMock->expects($this->once())
1372
                ->method('create')
1373
                ->with($this->logicalOr($spiContentCreateStruct, $spiContentCreateStruct2))
1374
                ->will($this->returnValue($spiContent));
1375
1376
            $repositoryMock->expects($this->once())->method('commit');
1377
            $domainMapperMock->expects($this->once())
1378
                ->method('buildContentDomainObject')
1379
                ->with(
1380
                    $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content'),
1381
                    $this->equalTo(null)
1382
                );
1383
1384
            $mockedService->createContent($contentCreateStruct, []);
1385
        }
1386
1387
        return $contentCreateStruct;
1388
    }
1389
1390
    public function providerForTestCreateContentNonRedundantFieldSet1()
1391
    {
1392
        $spiFields = [
1393
            new SPIField(
1394
                [
1395
                    'fieldDefinitionId' => 'fieldDefinitionId',
1396
                    'type' => 'fieldTypeIdentifier',
1397
                    'value' => 'newValue',
1398
                    'languageCode' => 'eng-US',
1399
                ]
1400
            ),
1401
        ];
1402
1403
        return [
1404
            // 0. Without language set
1405
            [
1406
                'eng-US',
1407
                [
1408
                    new Field(
1409
                        [
1410
                            'fieldDefIdentifier' => 'identifier',
1411
                            'value' => 'newValue',
1412
                            'languageCode' => 'eng-US',
1413
                        ]
1414
                    ),
1415
                ],
1416
                $spiFields,
1417
            ],
1418
            // 1. Without language set
1419
            [
1420
                'eng-US',
1421
                [
1422
                    new Field(
1423
                        [
1424
                            'fieldDefIdentifier' => 'identifier',
1425
                            'value' => 'newValue',
1426
                            'languageCode' => null,
1427
                        ]
1428
                    ),
1429
                ],
1430
                $spiFields,
1431
            ],
1432
        ];
1433
    }
1434
1435
    /**
1436
     * Test for the createContent() method.
1437
     *
1438
     * Testing the simplest use case.
1439
     *
1440
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1441
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
1442
     * @covers \eZ\Publish\Core\Repository\ContentService::cloneField
1443
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
1444
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1445
     * @dataProvider providerForTestCreateContentNonRedundantFieldSet1
1446
     */
1447 View Code Duplication
    public function testCreateContentNonRedundantFieldSet1($mainLanguageCode, $structFields, $spiFields)
1448
    {
1449
        $fieldDefinitions = [
1450
            new FieldDefinition(
1451
                [
1452
                    'id' => 'fieldDefinitionId',
1453
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1454
                    'isTranslatable' => false,
1455
                    'identifier' => 'identifier',
1456
                    'isRequired' => false,
1457
                    'defaultValue' => 'defaultValue',
1458
                ]
1459
            ),
1460
        ];
1461
1462
        $this->assertForTestCreateContentNonRedundantFieldSet(
1463
            $mainLanguageCode,
1464
            $structFields,
1465
            $spiFields,
1466
            $fieldDefinitions
1467
        );
1468
    }
1469
1470
    public function providerForTestCreateContentNonRedundantFieldSet2()
1471
    {
1472
        $spiFields = [
1473
            new SPIField(
1474
                [
1475
                    'fieldDefinitionId' => 'fieldDefinitionId1',
1476
                    'type' => 'fieldTypeIdentifier',
1477
                    'value' => 'newValue1',
1478
                    'languageCode' => 'eng-US',
1479
                ]
1480
            ),
1481
            new SPIField(
1482
                [
1483
                    'fieldDefinitionId' => 'fieldDefinitionId2',
1484
                    'type' => 'fieldTypeIdentifier',
1485
                    'value' => 'newValue2',
1486
                    'languageCode' => 'ger-DE',
1487
                ]
1488
            ),
1489
        ];
1490
1491
        return [
1492
            // 0. With language set
1493
            [
1494
                'eng-US',
1495
                [
1496
                    new Field(
1497
                        [
1498
                            'fieldDefIdentifier' => 'identifier1',
1499
                            'value' => 'newValue1',
1500
                            'languageCode' => 'eng-US',
1501
                        ]
1502
                    ),
1503
                    new Field(
1504
                        [
1505
                            'fieldDefIdentifier' => 'identifier2',
1506
                            'value' => 'newValue2',
1507
                            'languageCode' => 'ger-DE',
1508
                        ]
1509
                    ),
1510
                ],
1511
                $spiFields,
1512
            ],
1513
            // 1. Without language set
1514
            [
1515
                'eng-US',
1516
                [
1517
                    new Field(
1518
                        [
1519
                            'fieldDefIdentifier' => 'identifier1',
1520
                            'value' => 'newValue1',
1521
                            'languageCode' => null,
1522
                        ]
1523
                    ),
1524
                    new Field(
1525
                        [
1526
                            'fieldDefIdentifier' => 'identifier2',
1527
                            'value' => 'newValue2',
1528
                            'languageCode' => 'ger-DE',
1529
                        ]
1530
                    ),
1531
                ],
1532
                $spiFields,
1533
            ],
1534
        ];
1535
    }
1536
1537
    /**
1538
     * Test for the createContent() method.
1539
     *
1540
     * Testing multiple languages with multiple translatable fields with empty default value.
1541
     *
1542
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1543
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
1544
     * @covers \eZ\Publish\Core\Repository\ContentService::cloneField
1545
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
1546
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1547
     * @dataProvider providerForTestCreateContentNonRedundantFieldSet2
1548
     */
1549
    public function testCreateContentNonRedundantFieldSet2($mainLanguageCode, $structFields, $spiFields)
1550
    {
1551
        $fieldDefinitions = [
1552
            new FieldDefinition(
1553
                [
1554
                    'id' => 'fieldDefinitionId1',
1555
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1556
                    'isTranslatable' => true,
1557
                    'identifier' => 'identifier1',
1558
                    'isRequired' => false,
1559
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
1560
                ]
1561
            ),
1562
            new FieldDefinition(
1563
                [
1564
                    'id' => 'fieldDefinitionId2',
1565
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1566
                    'isTranslatable' => true,
1567
                    'identifier' => 'identifier2',
1568
                    'isRequired' => false,
1569
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
1570
                ]
1571
            ),
1572
        ];
1573
1574
        $this->assertForTestCreateContentNonRedundantFieldSet(
1575
            $mainLanguageCode,
1576
            $structFields,
1577
            $spiFields,
1578
            $fieldDefinitions
1579
        );
1580
    }
1581
1582
    public function providerForTestCreateContentNonRedundantFieldSetComplex()
1583
    {
1584
        $spiFields0 = [
1585
            new SPIField(
1586
                [
1587
                    'fieldDefinitionId' => 'fieldDefinitionId2',
1588
                    'type' => 'fieldTypeIdentifier',
1589
                    'value' => 'defaultValue2',
1590
                    'languageCode' => 'eng-US',
1591
                ]
1592
            ),
1593
            new SPIField(
1594
                [
1595
                    'fieldDefinitionId' => 'fieldDefinitionId4',
1596
                    'type' => 'fieldTypeIdentifier',
1597
                    'value' => 'defaultValue4',
1598
                    'languageCode' => 'eng-US',
1599
                ]
1600
            ),
1601
        ];
1602
        $spiFields1 = [
1603
            new SPIField(
1604
                [
1605
                    'fieldDefinitionId' => 'fieldDefinitionId1',
1606
                    'type' => 'fieldTypeIdentifier',
1607
                    'value' => 'newValue1',
1608
                    'languageCode' => 'ger-DE',
1609
                ]
1610
            ),
1611
            new SPIField(
1612
                [
1613
                    'fieldDefinitionId' => 'fieldDefinitionId2',
1614
                    'type' => 'fieldTypeIdentifier',
1615
                    'value' => 'defaultValue2',
1616
                    'languageCode' => 'ger-DE',
1617
                ]
1618
            ),
1619
            new SPIField(
1620
                [
1621
                    'fieldDefinitionId' => 'fieldDefinitionId2',
1622
                    'type' => 'fieldTypeIdentifier',
1623
                    'value' => 'newValue2',
1624
                    'languageCode' => 'eng-US',
1625
                ]
1626
            ),
1627
            new SPIField(
1628
                [
1629
                    'fieldDefinitionId' => 'fieldDefinitionId4',
1630
                    'type' => 'fieldTypeIdentifier',
1631
                    'value' => 'newValue4',
1632
                    'languageCode' => 'eng-US',
1633
                ]
1634
            ),
1635
        ];
1636
1637
        return [
1638
            // 0. Creating by default values only
1639
            [
1640
                'eng-US',
1641
                [],
1642
                $spiFields0,
1643
            ],
1644
            // 1. Multiple languages with language set
1645
            [
1646
                'eng-US',
1647
                [
1648
                    new Field(
1649
                        [
1650
                            'fieldDefIdentifier' => 'identifier1',
1651
                            'value' => 'newValue1',
1652
                            'languageCode' => 'ger-DE',
1653
                        ]
1654
                    ),
1655
                    new Field(
1656
                        [
1657
                            'fieldDefIdentifier' => 'identifier2',
1658
                            'value' => 'newValue2',
1659
                            'languageCode' => 'eng-US',
1660
                        ]
1661
                    ),
1662
                    new Field(
1663
                        [
1664
                            'fieldDefIdentifier' => 'identifier4',
1665
                            'value' => 'newValue4',
1666
                            'languageCode' => 'eng-US',
1667
                        ]
1668
                    ),
1669
                ],
1670
                $spiFields1,
1671
            ],
1672
            // 2. Multiple languages without language set
1673
            [
1674
                'eng-US',
1675
                [
1676
                    new Field(
1677
                        [
1678
                            'fieldDefIdentifier' => 'identifier1',
1679
                            'value' => 'newValue1',
1680
                            'languageCode' => 'ger-DE',
1681
                        ]
1682
                    ),
1683
                    new Field(
1684
                        [
1685
                            'fieldDefIdentifier' => 'identifier2',
1686
                            'value' => 'newValue2',
1687
                            'languageCode' => null,
1688
                        ]
1689
                    ),
1690
                    new Field(
1691
                        [
1692
                            'fieldDefIdentifier' => 'identifier4',
1693
                            'value' => 'newValue4',
1694
                            'languageCode' => null,
1695
                        ]
1696
                    ),
1697
                ],
1698
                $spiFields1,
1699
            ],
1700
        ];
1701
    }
1702
1703
    protected function fixturesForTestCreateContentNonRedundantFieldSetComplex()
1704
    {
1705
        return [
1706
            new FieldDefinition(
1707
                [
1708
                    'id' => 'fieldDefinitionId1',
1709
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1710
                    'isTranslatable' => true,
1711
                    'identifier' => 'identifier1',
1712
                    'isRequired' => false,
1713
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
1714
                ]
1715
            ),
1716
            new FieldDefinition(
1717
                [
1718
                    'id' => 'fieldDefinitionId2',
1719
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1720
                    'isTranslatable' => true,
1721
                    'identifier' => 'identifier2',
1722
                    'isRequired' => false,
1723
                    'defaultValue' => 'defaultValue2',
1724
                ]
1725
            ),
1726
            new FieldDefinition(
1727
                [
1728
                    'id' => 'fieldDefinitionId3',
1729
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1730
                    'isTranslatable' => false,
1731
                    'identifier' => 'identifier3',
1732
                    'isRequired' => false,
1733
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
1734
                ]
1735
            ),
1736
            new FieldDefinition(
1737
                [
1738
                    'id' => 'fieldDefinitionId4',
1739
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1740
                    'isTranslatable' => false,
1741
                    'identifier' => 'identifier4',
1742
                    'isRequired' => false,
1743
                    'defaultValue' => 'defaultValue4',
1744
                ]
1745
            ),
1746
        ];
1747
    }
1748
1749
    /**
1750
     * Test for the createContent() method.
1751
     *
1752
     * Testing multiple languages with multiple translatable fields with empty default value.
1753
     *
1754
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1755
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
1756
     * @covers \eZ\Publish\Core\Repository\ContentService::cloneField
1757
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
1758
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1759
     * @dataProvider providerForTestCreateContentNonRedundantFieldSetComplex
1760
     */
1761
    public function testCreateContentNonRedundantFieldSetComplex($mainLanguageCode, $structFields, $spiFields)
1762
    {
1763
        $fieldDefinitions = $this->fixturesForTestCreateContentNonRedundantFieldSetComplex();
1764
1765
        $this->assertForTestCreateContentNonRedundantFieldSet(
1766
            $mainLanguageCode,
1767
            $structFields,
1768
            $spiFields,
1769
            $fieldDefinitions
1770
        );
1771
    }
1772
1773 View Code Duplication
    public function providerForTestCreateContentWithInvalidLanguage()
1774
    {
1775
        return [
1776
            [
1777
                'eng-GB',
1778
                [
1779
                    new Field(
1780
                        [
1781
                            'fieldDefIdentifier' => 'identifier',
1782
                            'value' => 'newValue',
1783
                            'languageCode' => 'Klingon',
1784
                        ]
1785
                    ),
1786
                ],
1787
            ],
1788
            [
1789
                'Klingon',
1790
                [
1791
                    new Field(
1792
                        [
1793
                            'fieldDefIdentifier' => 'identifier',
1794
                            'value' => 'newValue',
1795
                            'languageCode' => 'eng-GB',
1796
                        ]
1797
                    ),
1798
                ],
1799
            ],
1800
        ];
1801
    }
1802
1803
    /**
1804
     * Test for the updateContent() method.
1805
     *
1806
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1807
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1808
     * @dataProvider providerForTestCreateContentWithInvalidLanguage
1809
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1810
     * @expectedExceptionMessage Could not find 'Language' with identifier 'Klingon'
1811
     */
1812
    public function testCreateContentWithInvalidLanguage($mainLanguageCode, $structFields)
1813
    {
1814
        $repositoryMock = $this->getRepositoryMock();
1815
        $mockedService = $this->getPartlyMockedContentService();
1816
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
1817
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
1818
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
1819
        $domainMapperMock = $this->getDomainMapperMock();
1820
        $contentType = new ContentType(
1821
            [
1822
                'id' => 123,
1823
                'fieldDefinitions' => [],
1824
            ]
1825
        );
1826
        $contentCreateStruct = new ContentCreateStruct(
1827
            [
1828
                'fields' => $structFields,
1829
                'mainLanguageCode' => $mainLanguageCode,
1830
                'contentType' => $contentType,
1831
                'alwaysAvailable' => false,
1832
                'ownerId' => 169,
1833
                'sectionId' => 1,
1834
            ]
1835
        );
1836
1837
        $languageHandlerMock->expects($this->any())
1838
            ->method('loadByLanguageCode')
1839
            ->with($this->isType('string'))
1840
            ->will(
1841
                $this->returnCallback(
1842 View Code Duplication
                    function ($languageCode) {
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...
1843
                        if ($languageCode === 'Klingon') {
1844
                            throw new NotFoundException('Language', 'Klingon');
1845
                        }
1846
1847
                        return new Language(['id' => 4242]);
1848
                    }
1849
                )
1850
            );
1851
1852
        $contentTypeServiceMock->expects($this->once())
1853
            ->method('loadContentType')
1854
            ->with($this->equalTo($contentType->id))
1855
            ->will($this->returnValue($contentType));
1856
1857
        $repositoryMock->expects($this->once())
1858
            ->method('getContentTypeService')
1859
            ->will($this->returnValue($contentTypeServiceMock));
1860
1861
        $that = $this;
1862
        $repositoryMock->expects($this->once())
1863
            ->method('canUser')
1864
            ->with(
1865
                $this->equalTo('content'),
1866
                $this->equalTo('create'),
1867
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
1868
                $this->equalTo([])
1869
            )->will(
1870
                $this->returnCallback(
1871
                    function () use ($that, $contentCreateStruct) {
1872
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
1873
1874
                        return true;
1875
                    }
1876
                )
1877
            );
1878
1879
        $domainMapperMock->expects($this->once())
1880
            ->method('getUniqueHash')
1881
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
1882
            ->will(
1883
                $this->returnCallback(
1884
                    function ($object) use ($that, $contentCreateStruct) {
1885
                        $that->assertEquals($contentCreateStruct, $object);
1886
1887
                        return 'hash';
1888
                    }
1889
                )
1890
            );
1891
1892
        $mockedService->createContent($contentCreateStruct, []);
1893
    }
1894
1895
    protected function assertForCreateContentContentValidationException(
1896
        $mainLanguageCode,
1897
        $structFields,
1898
        $fieldDefinitions = []
1899
    ) {
1900
        $repositoryMock = $this->getRepositoryMock();
1901
        $mockedService = $this->getPartlyMockedContentService(['loadContentByRemoteId']);
1902
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
1903
        $contentType = new ContentType(
1904
            [
1905
                'id' => 123,
1906
                'fieldDefinitions' => $fieldDefinitions,
1907
            ]
1908
        );
1909
        $contentCreateStruct = new ContentCreateStruct(
1910
            [
1911
                'ownerId' => 169,
1912
                'alwaysAvailable' => false,
1913
                'remoteId' => 'faraday',
1914
                'mainLanguageCode' => $mainLanguageCode,
1915
                'fields' => $structFields,
1916
                'contentType' => $contentType,
1917
            ]
1918
        );
1919
1920
        $contentTypeServiceMock->expects($this->once())
1921
            ->method('loadContentType')
1922
            ->with($this->equalTo(123))
1923
            ->will($this->returnValue($contentType));
1924
1925
        $repositoryMock->expects($this->once())
1926
            ->method('getContentTypeService')
1927
            ->will($this->returnValue($contentTypeServiceMock));
1928
1929
        $repositoryMock->expects($this->once())
1930
            ->method('canUser')
1931
            ->with(
1932
                $this->equalTo('content'),
1933
                $this->equalTo('create'),
1934
                $this->isInstanceOf($contentCreateStruct),
1935
                $this->equalTo([])
1936
            )->will($this->returnValue(true));
1937
1938
        $mockedService->expects($this->once())
1939
            ->method('loadContentByRemoteId')
1940
            ->with($contentCreateStruct->remoteId)
1941
            ->will(
1942
                $this->throwException(new NotFoundException('Content', 'faraday'))
1943
            );
1944
1945
        $mockedService->createContent($contentCreateStruct, []);
1946
    }
1947
1948 View Code Duplication
    public function providerForTestCreateContentThrowsContentValidationExceptionFieldDefinition()
1949
    {
1950
        return [
1951
            [
1952
                'eng-GB',
1953
                [
1954
                    new Field(
1955
                        [
1956
                            'fieldDefIdentifier' => 'identifier',
1957
                            'value' => 'newValue',
1958
                            'languageCode' => 'eng-GB',
1959
                        ]
1960
                    ),
1961
                ],
1962
            ],
1963
        ];
1964
    }
1965
1966
    /**
1967
     * Test for the createContent() method.
1968
     *
1969
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1970
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
1971
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1972
     * @dataProvider providerForTestCreateContentThrowsContentValidationExceptionFieldDefinition
1973
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentValidationException
1974
     * @expectedExceptionMessage Field definition 'identifier' does not exist in given ContentType
1975
     */
1976
    public function testCreateContentThrowsContentValidationExceptionFieldDefinition($mainLanguageCode, $structFields)
1977
    {
1978
        $this->assertForCreateContentContentValidationException(
1979
            $mainLanguageCode,
1980
            $structFields,
1981
            []
1982
        );
1983
    }
1984
1985 View Code Duplication
    public function providerForTestCreateContentThrowsContentValidationExceptionTranslation()
1986
    {
1987
        return [
1988
            [
1989
                'eng-GB',
1990
                [
1991
                    new Field(
1992
                        [
1993
                            'fieldDefIdentifier' => 'identifier',
1994
                            'value' => 'newValue',
1995
                            'languageCode' => 'eng-US',
1996
                        ]
1997
                    ),
1998
                ],
1999
            ],
2000
        ];
2001
    }
2002
2003
    /**
2004
     * Test for the createContent() method.
2005
     *
2006
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2007
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2008
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2009
     * @dataProvider providerForTestCreateContentThrowsContentValidationExceptionTranslation
2010
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentValidationException
2011
     * @expectedExceptionMessage A value is set for non translatable field definition 'identifier' with language 'eng-US'
2012
     */
2013 View Code Duplication
    public function testCreateContentThrowsContentValidationExceptionTranslation($mainLanguageCode, $structFields)
2014
    {
2015
        $fieldDefinitions = [
2016
            new FieldDefinition(
2017
                [
2018
                    'id' => 'fieldDefinitionId1',
2019
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2020
                    'isTranslatable' => false,
2021
                    'identifier' => 'identifier',
2022
                    'isRequired' => false,
2023
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
2024
                ]
2025
            ),
2026
        ];
2027
2028
        $this->assertForCreateContentContentValidationException(
2029
            $mainLanguageCode,
2030
            $structFields,
2031
            $fieldDefinitions
2032
        );
2033
    }
2034
2035
    /**
2036
     * Asserts behaviour necessary for testing ContentFieldValidationException because of required
2037
     * field being empty.
2038
     *
2039
     * @param string $mainLanguageCode
2040
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2041
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
2042
     *
2043
     * @return mixed
2044
     */
2045
    protected function assertForTestCreateContentRequiredField(
2046
        $mainLanguageCode,
2047
        array $structFields,
2048
        array $fieldDefinitions
2049
    ) {
2050
        $repositoryMock = $this->getRepositoryMock();
2051
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
2052
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
2053
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
2054
        $fieldTypeServiceMock = $this->getFieldTypeServiceMock();
0 ignored issues
show
Unused Code introduced by
$fieldTypeServiceMock 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...
2055
        $domainMapperMock = $this->getDomainMapperMock();
2056
        $fieldTypeMock = $this->getMock('eZ\\Publish\\SPI\\FieldType\\FieldType');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
2057
        $contentType = new ContentType(
2058
            [
2059
                'id' => 123,
2060
                'fieldDefinitions' => $fieldDefinitions,
2061
                'nameSchema' => '<nameSchema>',
2062
            ]
2063
        );
2064
        $contentCreateStruct = new ContentCreateStruct(
2065
            [
2066
                'fields' => $structFields,
2067
                'mainLanguageCode' => $mainLanguageCode,
2068
                'contentType' => $contentType,
2069
                'alwaysAvailable' => false,
2070
                'ownerId' => 169,
2071
                'sectionId' => 1,
2072
            ]
2073
        );
2074
2075
        $languageHandlerMock->expects($this->any())
2076
            ->method('loadByLanguageCode')
2077
            ->with($this->isType('string'))
2078
            ->will(
2079
                $this->returnCallback(
2080
                    function () {
2081
                        return new Language(['id' => 4242]);
2082
                    }
2083
                )
2084
            );
2085
2086
        $contentTypeServiceMock->expects($this->once())
2087
            ->method('loadContentType')
2088
            ->with($this->equalTo($contentType->id))
2089
            ->will($this->returnValue($contentType));
2090
2091
        $repositoryMock->expects($this->once())
2092
            ->method('getContentTypeService')
2093
            ->will($this->returnValue($contentTypeServiceMock));
2094
2095
        $that = $this;
2096
        $repositoryMock->expects($this->once())
2097
            ->method('canUser')
2098
            ->with(
2099
                $this->equalTo('content'),
2100
                $this->equalTo('create'),
2101
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
2102
                $this->equalTo([])
2103
            )->will(
2104
                $this->returnCallback(
2105
                    function () use ($that, $contentCreateStruct) {
2106
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
2107
2108
                        return true;
2109
                    }
2110
                )
2111
            );
2112
2113
        $domainMapperMock->expects($this->once())
2114
            ->method('getUniqueHash')
2115
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
2116
            ->will(
2117
                $this->returnCallback(
2118
                    function ($object) use ($that, $contentCreateStruct) {
2119
                        $that->assertEquals($contentCreateStruct, $object);
2120
2121
                        return 'hash';
2122
                    }
2123
                )
2124
            );
2125
2126
        $fieldTypeMock->expects($this->any())
2127
            ->method('acceptValue')
2128
            ->will(
2129
                $this->returnCallback(
2130
                    function ($valueString) {
2131
                        return new ValueStub($valueString);
2132
                    }
2133
                )
2134
            );
2135
2136
        $emptyValue = self::EMPTY_FIELD_VALUE;
2137
        $fieldTypeMock->expects($this->any())
2138
            ->method('isEmptyValue')
2139
            ->will(
2140
                $this->returnCallback(
2141
                    function (ValueStub $value) use ($emptyValue) {
2142
                        return $emptyValue === (string)$value;
2143
                    }
2144
                )
2145
            );
2146
2147
        $fieldTypeMock->expects($this->any())
2148
            ->method('validate')
2149
            ->will($this->returnValue([]));
2150
2151
        $this->getFieldTypeRegistryMock()->expects($this->any())
2152
            ->method('getFieldType')
2153
            ->will($this->returnValue($fieldTypeMock));
2154
2155
        return $contentCreateStruct;
2156
    }
2157
2158 View Code Duplication
    public function providerForTestCreateContentThrowsContentValidationExceptionRequiredField()
2159
    {
2160
        return [
2161
            [
2162
                'eng-US',
2163
                [
2164
                    new Field(
2165
                        [
2166
                            'fieldDefIdentifier' => 'identifier',
2167
                            'value' => self::EMPTY_FIELD_VALUE,
2168
                            'languageCode' => null,
2169
                        ]
2170
                    ),
2171
                ],
2172
                'identifier',
2173
                'eng-US',
2174
            ],
2175
        ];
2176
    }
2177
2178
    /**
2179
     * Test for the createContent() method.
2180
     *
2181
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2182
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2183
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2184
     * @dataProvider providerForTestCreateContentThrowsContentValidationExceptionRequiredField
2185
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
2186
     */
2187
    public function testCreateContentRequiredField(
2188
        $mainLanguageCode,
2189
        $structFields,
2190
        $identifier,
2191
        $languageCode
2192
    ) {
2193
        $fieldDefinitions = [
2194
            new FieldDefinition(
2195
                [
2196
                    'id' => 'fieldDefinitionId',
2197
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2198
                    'isTranslatable' => true,
2199
                    'identifier' => 'identifier',
2200
                    'isRequired' => true,
2201
                    'defaultValue' => 'defaultValue',
2202
                ]
2203
            ),
2204
        ];
2205
        $contentCreateStruct = $this->assertForTestCreateContentRequiredField(
2206
            $mainLanguageCode,
2207
            $structFields,
2208
            $fieldDefinitions
2209
        );
2210
2211
        $mockedService = $this->getPartlyMockedContentService();
2212
2213
        try {
2214
            $mockedService->createContent($contentCreateStruct, []);
2215
        } catch (ContentValidationException $e) {
2216
            $this->assertEquals(
2217
                "Value for required field definition '{$identifier}' with language '{$languageCode}' is empty",
2218
                $e->getMessage()
2219
            );
2220
2221
            throw $e;
2222
        }
2223
    }
2224
2225
    /**
2226
     * Asserts behaviour necessary for testing ContentFieldValidationException because of
2227
     * field not being valid.
2228
     *
2229
     * @param string $mainLanguageCode
2230
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2231
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
2232
     *
2233
     * @return mixed
2234
     */
2235
    protected function assertForTestCreateContentThrowsContentFieldValidationException(
2236
        $mainLanguageCode,
2237
        array $structFields,
2238
        array $fieldDefinitions
2239
    ) {
2240
        $repositoryMock = $this->getRepositoryMock();
2241
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
2242
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
2243
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
2244
        $fieldTypeServiceMock = $this->getFieldTypeServiceMock();
0 ignored issues
show
Unused Code introduced by
$fieldTypeServiceMock 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...
2245
        $domainMapperMock = $this->getDomainMapperMock();
2246
        $relationProcessorMock = $this->getRelationProcessorMock();
2247
        $fieldTypeMock = $this->getMock('eZ\\Publish\\SPI\\FieldType\\FieldType');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
2248
        $languageCodes = $this->determineLanguageCodesForCreate($mainLanguageCode, $structFields);
2249
        $contentType = new ContentType(
2250
            [
2251
                'id' => 123,
2252
                'fieldDefinitions' => $fieldDefinitions,
2253
                'nameSchema' => '<nameSchema>',
2254
            ]
2255
        );
2256
        $contentCreateStruct = new ContentCreateStruct(
2257
            [
2258
                'fields' => $structFields,
2259
                'mainLanguageCode' => $mainLanguageCode,
2260
                'contentType' => $contentType,
2261
                'alwaysAvailable' => false,
2262
                'ownerId' => 169,
2263
                'sectionId' => 1,
2264
            ]
2265
        );
2266
2267
        $languageHandlerMock->expects($this->any())
2268
            ->method('loadByLanguageCode')
2269
            ->with($this->isType('string'))
2270
            ->will(
2271
                $this->returnCallback(
2272
                    function () {
2273
                        return new Language(['id' => 4242]);
2274
                    }
2275
                )
2276
            );
2277
2278
        $contentTypeServiceMock->expects($this->once())
2279
            ->method('loadContentType')
2280
            ->with($this->equalTo($contentType->id))
2281
            ->will($this->returnValue($contentType));
2282
2283
        $repositoryMock->expects($this->once())
2284
            ->method('getContentTypeService')
2285
            ->will($this->returnValue($contentTypeServiceMock));
2286
2287
        $that = $this;
2288
        $repositoryMock->expects($this->once())
2289
            ->method('canUser')
2290
            ->with(
2291
                $this->equalTo('content'),
2292
                $this->equalTo('create'),
2293
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
2294
                $this->equalTo([])
2295
            )->will(
2296
                $this->returnCallback(
2297
                    function () use ($that, $contentCreateStruct) {
2298
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
2299
2300
                        return true;
2301
                    }
2302
                )
2303
            );
2304
2305
        $domainMapperMock->expects($this->once())
2306
            ->method('getUniqueHash')
2307
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
2308
            ->will(
2309
                $this->returnCallback(
2310
                    function ($object) use ($that, $contentCreateStruct) {
2311
                        $that->assertEquals($contentCreateStruct, $object);
2312
2313
                        return 'hash';
2314
                    }
2315
                )
2316
            );
2317
2318
        $this->getFieldTypeRegistryMock()->expects($this->any())
2319
            ->method('getFieldType')
2320
            ->will($this->returnValue($fieldTypeMock));
2321
2322
        $relationProcessorMock
2323
            ->expects($this->any())
2324
            ->method('appendFieldRelations')
2325
            ->with(
2326
                $this->isType('array'),
2327
                $this->isType('array'),
2328
                $this->isInstanceOf('eZ\\Publish\\SPI\\FieldType\\FieldType'),
2329
                $this->isInstanceOf('eZ\\Publish\\Core\\FieldType\\Value'),
2330
                $this->anything()
2331
            );
2332
2333
        $fieldValues = $this->determineValuesForCreate(
2334
            $mainLanguageCode,
2335
            $structFields,
2336
            $fieldDefinitions,
2337
            $languageCodes
2338
        );
2339
        $allFieldErrors = [];
2340
        $validateCount = 0;
2341
        $emptyValue = self::EMPTY_FIELD_VALUE;
2342
        foreach ($contentType->getFieldDefinitions() as $fieldDefinition) {
2343
            foreach ($fieldValues[$fieldDefinition->identifier] as $languageCode => $value) {
2344
                $fieldTypeMock->expects($this->at($validateCount++))
2345
                    ->method('acceptValue')
2346
                    ->will(
2347
                        $this->returnCallback(
2348
                            function ($valueString) {
2349
                                return new ValueStub($valueString);
2350
                            }
2351
                        )
2352
                    );
2353
2354
                $fieldTypeMock->expects($this->at($validateCount++))
2355
                    ->method('isEmptyValue')
2356
                    ->will(
2357
                        $this->returnCallback(
2358
                            function (ValueStub $value) use ($emptyValue) {
2359
                                return $emptyValue === (string)$value;
2360
                            }
2361
                        )
2362
                    );
2363
2364
                if (self::EMPTY_FIELD_VALUE === (string)$value) {
2365
                    continue;
2366
                }
2367
2368
                $fieldTypeMock->expects($this->at($validateCount++))
2369
                    ->method('validate')
2370
                    ->with(
2371
                        $this->equalTo($fieldDefinition),
2372
                        $this->equalTo($value)
2373
                    )->will($this->returnArgument(1));
2374
2375
                $allFieldErrors[$fieldDefinition->id][$languageCode] = $value;
2376
            }
2377
        }
2378
2379
        return [$contentCreateStruct, $allFieldErrors];
2380
    }
2381
2382
    public function providerForTestCreateContentThrowsContentFieldValidationException()
2383
    {
2384
        return $this->providerForTestCreateContentNonRedundantFieldSetComplex();
2385
    }
2386
2387
    /**
2388
     * Test for the createContent() method.
2389
     *
2390
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2391
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2392
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2393
     * @dataProvider providerForTestCreateContentThrowsContentFieldValidationException
2394
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
2395
     * @expectedExceptionMessage Content fields did not validate
2396
     */
2397
    public function testCreateContentThrowsContentFieldValidationException($mainLanguageCode, $structFields)
2398
    {
2399
        $fieldDefinitions = $this->fixturesForTestCreateContentNonRedundantFieldSetComplex();
2400
        list($contentCreateStruct, $allFieldErrors) =
2401
            $this->assertForTestCreateContentThrowsContentFieldValidationException(
2402
                $mainLanguageCode,
2403
                $structFields,
2404
                $fieldDefinitions
2405
            );
2406
2407
        $mockedService = $this->getPartlyMockedContentService();
2408
2409
        try {
2410
            $mockedService->createContent($contentCreateStruct);
2411
        } catch (ContentFieldValidationException $e) {
2412
            $this->assertEquals($allFieldErrors, $e->getFieldErrors());
2413
            throw $e;
2414
        }
2415
    }
2416
2417
    /**
2418
     * Test for the createContent() method.
2419
     *
2420
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2421
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2422
     * @covers \eZ\Publish\Core\Repository\ContentService::buildSPILocationCreateStructs
2423
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2424
     */
2425
    public function testCreateContentWithLocations()
2426
    {
2427
        $spiFields = [
2428
            new SPIField(
2429
                [
2430
                    'fieldDefinitionId' => 'fieldDefinitionId',
2431
                    'type' => 'fieldTypeIdentifier',
2432
                    'value' => 'defaultValue',
2433
                    'languageCode' => 'eng-US',
2434
                ]
2435
            ),
2436
        ];
2437
        $fieldDefinitions = [
2438
            new FieldDefinition(
2439
                [
2440
                    'id' => 'fieldDefinitionId',
2441
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2442
                    'isTranslatable' => false,
2443
                    'identifier' => 'identifier',
2444
                    'isRequired' => false,
2445
                    'defaultValue' => 'defaultValue',
2446
                ]
2447
            ),
2448
        ];
2449
2450
        // Set up a simple case that will pass
2451
        $locationCreateStruct1 = new LocationCreateStruct(['parentLocationId' => 321]);
2452
        $locationCreateStruct2 = new LocationCreateStruct(['parentLocationId' => 654]);
2453
        $locationCreateStructs = [$locationCreateStruct1, $locationCreateStruct2];
2454
        $contentCreateStruct = $this->assertForTestCreateContentNonRedundantFieldSet(
2455
            'eng-US',
2456
            [],
2457
            $spiFields,
2458
            $fieldDefinitions,
2459
            $locationCreateStructs,
2460
            false,
2461
            // Do not execute
2462
            false
2463
        );
2464
2465
        $repositoryMock = $this->getRepositoryMock();
2466
        $mockedService = $this->getPartlyMockedContentService();
2467
        $locationServiceMock = $this->getLocationServiceMock();
2468
        /** @var \PHPUnit_Framework_MockObject_MockObject $handlerMock */
2469
        $handlerMock = $this->getPersistenceMock()->contentHandler();
2470
        $domainMapperMock = $this->getDomainMapperMock();
2471
        $spiLocationCreateStruct = new SPILocation\CreateStruct();
2472
        $parentLocation = new Location(['contentInfo' => new ContentInfo(['sectionId' => 1])]);
2473
2474
        $locationServiceMock->expects($this->at(0))
2475
            ->method('loadLocation')
2476
            ->with($this->equalTo(321))
2477
            ->will($this->returnValue($parentLocation));
2478
2479
        $locationServiceMock->expects($this->at(1))
2480
            ->method('loadLocation')
2481
            ->with($this->equalTo(654))
2482
            ->will($this->returnValue($parentLocation));
2483
2484
        $repositoryMock->expects($this->atLeastOnce())
2485
            ->method('getLocationService')
2486
            ->will($this->returnValue($locationServiceMock));
2487
2488
        $domainMapperMock->expects($this->at(1))
2489
            ->method('buildSPILocationCreateStruct')
2490
            ->with(
2491
                $this->equalTo($locationCreateStruct1),
2492
                $this->equalTo($parentLocation),
2493
                $this->equalTo(true),
2494
                $this->equalTo(null),
2495
                $this->equalTo(null)
2496
            )->will($this->returnValue($spiLocationCreateStruct));
2497
2498
        $domainMapperMock->expects($this->at(2))
2499
            ->method('buildSPILocationCreateStruct')
2500
            ->with(
2501
                $this->equalTo($locationCreateStruct2),
2502
                $this->equalTo($parentLocation),
2503
                $this->equalTo(false),
2504
                $this->equalTo(null),
2505
                $this->equalTo(null)
2506
            )->will($this->returnValue($spiLocationCreateStruct));
2507
2508
        $spiContentCreateStruct = new SPIContentCreateStruct(
2509
            [
2510
                'name' => [],
2511
                'typeId' => 123,
2512
                'sectionId' => 1,
2513
                'ownerId' => 169,
2514
                'remoteId' => 'hash',
2515
                'fields' => $spiFields,
2516
                'modified' => time(),
2517
                'initialLanguageId' => 4242,
2518
                'locations' => [$spiLocationCreateStruct, $spiLocationCreateStruct],
2519
            ]
2520
        );
2521
        $spiContentCreateStruct2 = clone $spiContentCreateStruct;
2522
        ++$spiContentCreateStruct2->modified;
2523
2524
        $spiContent = new SPIContent(
2525
            [
2526
                'versionInfo' => new SPIContent\VersionInfo(
2527
                    [
2528
                        'contentInfo' => new SPIContent\ContentInfo(['id' => 42]),
2529
                        'versionNo' => 7,
2530
                    ]
2531
                ),
2532
            ]
2533
        );
2534
2535
        $handlerMock->expects($this->once())
2536
            ->method('create')
2537
            ->with($this->logicalOr($spiContentCreateStruct, $spiContentCreateStruct2))
2538
            ->will($this->returnValue($spiContent));
2539
2540
        $domainMapperMock->expects($this->once())
2541
            ->method('buildContentDomainObject')
2542
            ->with(
2543
                $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content'),
2544
                $this->equalTo(null)
2545
            );
2546
2547
        $repositoryMock->expects($this->once())->method('commit');
2548
2549
        // Execute
2550
        $mockedService->createContent($contentCreateStruct, $locationCreateStructs);
2551
    }
2552
2553
    /**
2554
     * Test for the createContent() method.
2555
     *
2556
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2557
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2558
     * @covers \eZ\Publish\Core\Repository\ContentService::buildSPILocationCreateStructs
2559
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2560
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2561
     * @expectedExceptionMessage Multiple LocationCreateStructs with the same parent Location '321' are given
2562
     */
2563
    public function testCreateContentWithLocationsDuplicateUnderParent()
2564
    {
2565
        $fieldDefinitions = [
2566
            new FieldDefinition(
2567
                [
2568
                    'id' => 'fieldDefinitionId',
2569
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2570
                    'isTranslatable' => false,
2571
                    'identifier' => 'identifier',
2572
                    'isRequired' => false,
2573
                    'defaultValue' => 'defaultValue',
2574
                ]
2575
            ),
2576
        ];
2577
2578
        $repositoryMock = $this->getRepositoryMock();
2579
        $mockedService = $this->getPartlyMockedContentService();
2580
        $locationServiceMock = $this->getLocationServiceMock();
2581
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
2582
        $domainMapperMock = $this->getDomainMapperMock();
2583
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
2584
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
2585
        $spiLocationCreateStruct = new SPILocation\CreateStruct();
2586
        $parentLocation = new Location(['id' => 321]);
2587
        $locationCreateStruct = new LocationCreateStruct(['parentLocationId' => 321]);
2588
        $locationCreateStructs = [$locationCreateStruct, clone $locationCreateStruct];
2589
        $contentType = new ContentType(
2590
            [
2591
                'id' => 123,
2592
                'fieldDefinitions' => $fieldDefinitions,
2593
                'nameSchema' => '<nameSchema>',
2594
            ]
2595
        );
2596
        $contentCreateStruct = new ContentCreateStruct(
2597
            [
2598
                'fields' => [],
2599
                'mainLanguageCode' => 'eng-US',
2600
                'contentType' => $contentType,
2601
                'alwaysAvailable' => false,
2602
                'ownerId' => 169,
2603
                'sectionId' => 1,
2604
            ]
2605
        );
2606
2607
        $languageHandlerMock->expects($this->any())
2608
            ->method('loadByLanguageCode')
2609
            ->with($this->isType('string'))
2610
            ->will(
2611
                $this->returnCallback(
2612
                    function () {
2613
                        return new Language(['id' => 4242]);
2614
                    }
2615
                )
2616
            );
2617
2618
        $contentTypeServiceMock->expects($this->once())
2619
            ->method('loadContentType')
2620
            ->with($this->equalTo($contentType->id))
2621
            ->will($this->returnValue($contentType));
2622
2623
        $repositoryMock->expects($this->once())
2624
            ->method('getContentTypeService')
2625
            ->will($this->returnValue($contentTypeServiceMock));
2626
2627
        $that = $this;
2628
        $repositoryMock->expects($this->once())
2629
            ->method('canUser')
2630
            ->with(
2631
                $this->equalTo('content'),
2632
                $this->equalTo('create'),
2633
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
2634
                $this->equalTo($locationCreateStructs)
2635
            )->will(
2636
                $this->returnCallback(
2637
                    function () use ($that, $contentCreateStruct) {
2638
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
2639
2640
                        return true;
2641
                    }
2642
                )
2643
            );
2644
2645
        $domainMapperMock->expects($this->once())
2646
            ->method('getUniqueHash')
2647
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
2648
            ->will(
2649
                $this->returnCallback(
2650
                    function ($object) use ($that, $contentCreateStruct) {
2651
                        $that->assertEquals($contentCreateStruct, $object);
2652
2653
                        return 'hash';
2654
                    }
2655
                )
2656
            );
2657
2658
        $locationServiceMock->expects($this->once())
2659
            ->method('loadLocation')
2660
            ->with($this->equalTo(321))
2661
            ->will($this->returnValue($parentLocation));
2662
2663
        $repositoryMock->expects($this->any())
2664
            ->method('getLocationService')
2665
            ->will($this->returnValue($locationServiceMock));
2666
2667
        $domainMapperMock->expects($this->any())
2668
            ->method('buildSPILocationCreateStruct')
2669
            ->with(
2670
                $this->equalTo($locationCreateStruct),
2671
                $this->equalTo($parentLocation),
2672
                $this->equalTo(true),
2673
                $this->equalTo(null),
2674
                $this->equalTo(null)
2675
            )->will($this->returnValue($spiLocationCreateStruct));
2676
2677
        $mockedService->createContent(
2678
            $contentCreateStruct,
2679
            $locationCreateStructs
2680
        );
2681
    }
2682
2683
    /**
2684
     * Test for the createContent() method.
2685
     *
2686
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2687
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2688
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
2689
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2690
     */
2691
    public function testCreateContentObjectStates()
2692
    {
2693
        $spiFields = [
2694
            new SPIField(
2695
                [
2696
                    'fieldDefinitionId' => 'fieldDefinitionId',
2697
                    'type' => 'fieldTypeIdentifier',
2698
                    'value' => 'defaultValue',
2699
                    'languageCode' => 'eng-US',
2700
                ]
2701
            ),
2702
        ];
2703
        $fieldDefinitions = [
2704
            new FieldDefinition(
2705
                [
2706
                    'id' => 'fieldDefinitionId',
2707
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2708
                    'isTranslatable' => false,
2709
                    'identifier' => 'identifier',
2710
                    'isRequired' => false,
2711
                    'defaultValue' => 'defaultValue',
2712
                ]
2713
            ),
2714
        ];
2715
        $objectStateGroups = [
0 ignored issues
show
Unused Code introduced by
$objectStateGroups 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...
2716
            new SPIObjectStateGroup(['id' => 10]),
2717
            new SPIObjectStateGroup(['id' => 20]),
2718
        ];
2719
2720
        // Set up a simple case that will pass
2721
        $contentCreateStruct = $this->assertForTestCreateContentNonRedundantFieldSet(
2722
            'eng-US',
2723
            [],
2724
            $spiFields,
2725
            $fieldDefinitions,
2726
            [],
2727
            true,
2728
            // Do not execute
2729
            false
2730
        );
2731
        $timestamp = time();
2732
        $contentCreateStruct->modificationDate = new \DateTime("@{$timestamp}");
2733
2734
        $repositoryMock = $this->getRepositoryMock();
2735
        $mockedService = $this->getPartlyMockedContentService();
2736
        /** @var \PHPUnit_Framework_MockObject_MockObject $handlerMock */
2737
        $handlerMock = $this->getPersistenceMock()->contentHandler();
2738
        $domainMapperMock = $this->getDomainMapperMock();
2739
2740
        $this->mockGetDefaultObjectStates();
2741
        $this->mockSetDefaultObjectStates();
2742
2743
        $spiContentCreateStruct = new SPIContentCreateStruct(
2744
            [
2745
                'name' => [],
2746
                'typeId' => 123,
2747
                'sectionId' => 1,
2748
                'ownerId' => 169,
2749
                'remoteId' => 'hash',
2750
                'fields' => $spiFields,
2751
                'modified' => $timestamp,
2752
                'initialLanguageId' => 4242,
2753
                'locations' => [],
2754
            ]
2755
        );
2756
        $spiContentCreateStruct2 = clone $spiContentCreateStruct;
2757
        ++$spiContentCreateStruct2->modified;
2758
2759
        $spiContent = new SPIContent(
2760
            [
2761
                'versionInfo' => new SPIContent\VersionInfo(
2762
                    [
2763
                        'contentInfo' => new SPIContent\ContentInfo(['id' => 42]),
2764
                        'versionNo' => 7,
2765
                    ]
2766
                ),
2767
            ]
2768
        );
2769
2770
        $handlerMock->expects($this->once())
2771
            ->method('create')
2772
            ->with($this->equalTo($spiContentCreateStruct))
2773
            ->will($this->returnValue($spiContent));
2774
2775
        $domainMapperMock->expects($this->once())
2776
            ->method('buildContentDomainObject')
2777
            ->with(
2778
                $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content'),
2779
                $this->equalTo(null)
2780
            );
2781
2782
        $repositoryMock->expects($this->once())->method('commit');
2783
2784
        // Execute
2785
        $mockedService->createContent($contentCreateStruct, []);
2786
    }
2787
2788
    /**
2789
     * Test for the createContent() method.
2790
     *
2791
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2792
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2793
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
2794
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2795
     * @dataProvider providerForTestCreateContentThrowsContentValidationExceptionTranslation
2796
     * @expectedException \Exception
2797
     * @expectedExceptionMessage Store failed
2798
     */
2799
    public function testCreateContentWithRollback()
2800
    {
2801
        $fieldDefinitions = [
2802
            new FieldDefinition(
2803
                [
2804
                    'id' => 'fieldDefinitionId',
2805
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2806
                    'isTranslatable' => false,
2807
                    'identifier' => 'identifier',
2808
                    'isRequired' => false,
2809
                    'defaultValue' => 'defaultValue',
2810
                ]
2811
            ),
2812
        ];
2813
2814
        // Setup a simple case that will pass
2815
        $contentCreateStruct = $this->assertForTestCreateContentNonRedundantFieldSet(
2816
            'eng-US',
2817
            [],
2818
            [],
2819
            $fieldDefinitions,
2820
            [],
2821
            false,
2822
            // Do not execute test
2823
            false
2824
        );
2825
2826
        $repositoryMock = $this->getRepositoryMock();
2827
        $repositoryMock->expects($this->never())->method('commit');
2828
        $repositoryMock->expects($this->once())->method('rollback');
2829
2830
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
2831
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
2832
        $contentHandlerMock->expects($this->once())
2833
            ->method('create')
2834
            ->with($this->anything())
2835
            ->will($this->throwException(new \Exception('Store failed')));
2836
2837
        // Execute
2838
        $this->partlyMockedContentService->createContent($contentCreateStruct, []);
2839
    }
2840
2841
    public function providerForTestUpdateContentThrowsBadStateException()
2842
    {
2843
        return [
2844
            [VersionInfo::STATUS_PUBLISHED],
2845
            [VersionInfo::STATUS_ARCHIVED],
2846
        ];
2847
    }
2848
2849
    /**
2850
     * Test for the updateContent() method.
2851
     *
2852
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
2853
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
2854
     * @dataProvider providerForTestUpdateContentThrowsBadStateException
2855
     */
2856
    public function testUpdateContentThrowsBadStateException($status)
2857
    {
2858
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
2859
        $contentUpdateStruct = new ContentUpdateStruct();
2860
        $versionInfo = new VersionInfo(
2861
            [
2862
                'contentInfo' => new ContentInfo(['id' => 42]),
2863
                'versionNo' => 7,
2864
                'status' => $status,
2865
            ]
2866
        );
2867
        $content = new Content(
2868
            [
2869
                'versionInfo' => $versionInfo,
2870
                'internalFields' => [],
2871
            ]
2872
        );
2873
2874
        $mockedService->expects($this->once())
2875
            ->method('loadContent')
2876
            ->with(
2877
                $this->equalTo(42),
2878
                $this->equalTo(null),
2879
                $this->equalTo(7)
2880
            )->will(
2881
                $this->returnValue($content)
2882
            );
2883
2884
        $mockedService->updateContent($versionInfo, $contentUpdateStruct);
2885
    }
2886
2887
    /**
2888
     * Test for the updateContent() method.
2889
     *
2890
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
2891
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
2892
     */
2893
    public function testUpdateContentThrowsUnauthorizedException()
2894
    {
2895
        $repositoryMock = $this->getRepositoryMock();
2896
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
2897
        $contentUpdateStruct = new ContentUpdateStruct();
2898
        $versionInfo = new VersionInfo(
2899
            [
2900
                'contentInfo' => new ContentInfo(['id' => 42]),
2901
                'versionNo' => 7,
2902
                'status' => VersionInfo::STATUS_DRAFT,
2903
            ]
2904
        );
2905
        $content = new Content(
2906
            [
2907
                'versionInfo' => $versionInfo,
2908
                'internalFields' => [],
2909
            ]
2910
        );
2911
2912
        $mockedService->expects($this->once())
2913
            ->method('loadContent')
2914
            ->with(
2915
                $this->equalTo(42),
2916
                $this->equalTo(null),
2917
                $this->equalTo(7)
2918
            )->will(
2919
                $this->returnValue($content)
2920
            );
2921
2922
        $repositoryMock->expects($this->once())
2923
            ->method('canUser')
2924
            ->with(
2925
                $this->equalTo('content'),
2926
                $this->equalTo('edit'),
2927
                $this->equalTo($content)
2928
            )->will($this->returnValue(false));
2929
2930
        $mockedService->updateContent($versionInfo, $contentUpdateStruct);
2931
    }
2932
2933
    /**
2934
     * @param string $initialLanguageCode
2935
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2936
     * @param string[] $existingLanguages
2937
     *
2938
     * @return string[]
2939
     */
2940
    protected function determineLanguageCodesForUpdate($initialLanguageCode, array $structFields, $existingLanguages)
2941
    {
2942
        $languageCodes = array_fill_keys($existingLanguages, true);
2943
        if ($initialLanguageCode !== null) {
2944
            $languageCodes[$initialLanguageCode] = true;
2945
        }
2946
2947
        foreach ($structFields as $field) {
2948
            if ($field->languageCode === null || isset($languageCodes[$field->languageCode])) {
2949
                continue;
2950
            }
2951
2952
            $languageCodes[$field->languageCode] = true;
2953
        }
2954
2955
        return array_keys($languageCodes);
2956
    }
2957
2958
    /**
2959
     * @param string $initialLanguageCode
2960
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2961
     * @param string $mainLanguageCode
2962
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
2963
     *
2964
     * @return array
2965
     */
2966
    protected function mapStructFieldsForUpdate($initialLanguageCode, $structFields, $mainLanguageCode, $fieldDefinitions)
2967
    {
2968
        $initialLanguageCode = $initialLanguageCode ?: $mainLanguageCode;
2969
2970
        $mappedFieldDefinitions = [];
2971
        foreach ($fieldDefinitions as $fieldDefinition) {
2972
            $mappedFieldDefinitions[$fieldDefinition->identifier] = $fieldDefinition;
2973
        }
2974
2975
        $mappedStructFields = [];
2976
        foreach ($structFields as $structField) {
2977
            $identifier = $structField->fieldDefIdentifier;
2978
2979
            if ($structField->languageCode !== null) {
2980
                $languageCode = $structField->languageCode;
2981
            } elseif ($mappedFieldDefinitions[$identifier]->isTranslatable) {
2982
                $languageCode = $initialLanguageCode;
2983
            } else {
2984
                $languageCode = $mainLanguageCode;
2985
            }
2986
2987
            $mappedStructFields[$identifier][$languageCode] = (string)$structField->value;
2988
        }
2989
2990
        return $mappedStructFields;
2991
    }
2992
2993
    /**
2994
     * Returns full, possibly redundant array of field values, indexed by field definition
2995
     * identifier and language code.
2996
     *
2997
     * @param string $initialLanguageCode
2998
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2999
     * @param \eZ\Publish\Core\Repository\Values\Content\Content $content
3000
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
3001
     * @param array $languageCodes
3002
     *
3003
     * @return array
3004
     */
3005
    protected function determineValuesForUpdate(
3006
        $initialLanguageCode,
3007
        array $structFields,
3008
        Content $content,
3009
        array $fieldDefinitions,
3010
        array $languageCodes
3011
    ) {
3012
        $mainLanguageCode = $content->versionInfo->contentInfo->mainLanguageCode;
3013
3014
        $mappedStructFields = $this->mapStructFieldsForUpdate(
3015
            $initialLanguageCode,
3016
            $structFields,
3017
            $mainLanguageCode,
3018
            $fieldDefinitions
3019
        );
3020
3021
        $values = [];
3022
3023
        foreach ($fieldDefinitions as $fieldDefinition) {
3024
            $identifier = $fieldDefinition->identifier;
3025
            foreach ($languageCodes as $languageCode) {
3026 View Code Duplication
                if (!$fieldDefinition->isTranslatable) {
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...
3027
                    if (isset($mappedStructFields[$identifier][$mainLanguageCode])) {
3028
                        $values[$identifier][$languageCode] = $mappedStructFields[$identifier][$mainLanguageCode];
3029
                    } else {
3030
                        $values[$identifier][$languageCode] = (string)$content->fields[$identifier][$mainLanguageCode];
3031
                    }
3032
                    continue;
3033
                }
3034
3035 View Code Duplication
                if (isset($mappedStructFields[$identifier][$languageCode])) {
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...
3036
                    $values[$identifier][$languageCode] = $mappedStructFields[$identifier][$languageCode];
3037
                    continue;
3038
                }
3039
3040
                if (isset($content->fields[$identifier][$languageCode])) {
3041
                    $values[$identifier][$languageCode] = (string)$content->fields[$identifier][$languageCode];
3042
                    continue;
3043
                }
3044
3045
                $values[$identifier][$languageCode] = (string)$fieldDefinition->defaultValue;
3046
            }
3047
        }
3048
3049
        return $this->stubValues($values);
3050
    }
3051
3052
    protected function stubValues(array $fieldValues)
3053
    {
3054
        foreach ($fieldValues as &$languageValues) {
3055
            foreach ($languageValues as &$value) {
3056
                $value = new ValueStub($value);
3057
            }
3058
        }
3059
3060
        return $fieldValues;
3061
    }
3062
3063
    /**
3064
     * Asserts that calling updateContent() with given API field set causes calling
3065
     * Handler::updateContent() with given SPI field set.
3066
     *
3067
     * @param string $initialLanguageCode
3068
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
3069
     * @param \eZ\Publish\SPI\Persistence\Content\Field[] $spiFields
3070
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $existingFields
3071
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
3072
     * @param bool $execute
3073
     *
3074
     * @return mixed
3075
     */
3076
    protected function assertForTestUpdateContentNonRedundantFieldSet(
3077
        $initialLanguageCode,
3078
        array $structFields,
3079
        array $spiFields,
3080
        array $existingFields,
3081
        array $fieldDefinitions,
3082
        $execute = true
3083
    ) {
3084
        $repositoryMock = $this->getRepositoryMock();
3085
        $mockedService = $this->getPartlyMockedContentService(['loadContent', 'loadRelations']);
3086
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
3087
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
3088
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
3089
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
3090
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
3091
        $fieldTypeServiceMock = $this->getFieldTypeServiceMock();
0 ignored issues
show
Unused Code introduced by
$fieldTypeServiceMock 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...
3092
        $domainMapperMock = $this->getDomainMapperMock();
3093
        $relationProcessorMock = $this->getRelationProcessorMock();
3094
        $nameSchemaServiceMock = $this->getNameSchemaServiceMock();
3095
        $fieldTypeMock = $this->getMock('eZ\\Publish\\SPI\\FieldType\\FieldType');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
3096
        $existingLanguageCodes = array_map(
3097
            function (Field $field) {
3098
                return $field->languageCode;
3099
            },
3100
            $existingFields
3101
        );
3102
        $languageCodes = $this->determineLanguageCodesForUpdate(
3103
            $initialLanguageCode,
3104
            $structFields,
3105
            $existingLanguageCodes
3106
        );
3107
        $versionInfo = new VersionInfo(
3108
            [
3109
                'contentInfo' => new ContentInfo(
3110
                    [
3111
                        'id' => 42,
3112
                        'contentTypeId' => 24,
3113
                        'mainLanguageCode' => 'eng-GB',
3114
                    ]
3115
                ),
3116
                'versionNo' => 7,
3117
                'languageCodes' => $existingLanguageCodes,
3118
                'status' => VersionInfo::STATUS_DRAFT,
3119
            ]
3120
        );
3121
        $content = new Content(
3122
            [
3123
                'versionInfo' => $versionInfo,
3124
                'internalFields' => $existingFields,
3125
            ]
3126
        );
3127
        $contentType = new ContentType(['fieldDefinitions' => $fieldDefinitions]);
3128
3129
        $languageHandlerMock->expects($this->any())
3130
            ->method('loadByLanguageCode')
3131
            ->with($this->isType('string'))
3132
            ->will(
3133
                $this->returnCallback(
3134
                    function () {
3135
                        return new Language(['id' => 4242]);
3136
                    }
3137
                )
3138
            );
3139
3140
        $mockedService->expects($this->once())
3141
            ->method('loadContent')
3142
            ->with(
3143
                $this->equalTo(42),
3144
                $this->equalTo(null),
3145
                $this->equalTo(7)
3146
            )->will(
3147
                $this->returnValue($content)
3148
            );
3149
3150
        $repositoryMock->expects($this->once())->method('beginTransaction');
3151
3152
        $repositoryMock->expects($this->once())
3153
            ->method('canUser')
3154
            ->with(
3155
                $this->equalTo('content'),
3156
                $this->equalTo('edit'),
3157
                $this->equalTo($content)
3158
            )->will($this->returnValue(true));
3159
3160
        $contentTypeServiceMock->expects($this->once())
3161
            ->method('loadContentType')
3162
            ->with($this->equalTo(24))
3163
            ->will($this->returnValue($contentType));
3164
3165
        $repositoryMock->expects($this->once())
3166
            ->method('getContentTypeService')
3167
            ->will($this->returnValue($contentTypeServiceMock));
3168
3169
        $repositoryMock->expects($this->once())
3170
            ->method('getCurrentUserReference')
3171
            ->will($this->returnValue(new UserReference(169)));
3172
3173
        $fieldTypeMock->expects($this->any())
3174
            ->method('acceptValue')
3175
            ->will(
3176
                $this->returnCallback(
3177
                    function ($valueString) {
3178
                        return new ValueStub($valueString);
3179
                    }
3180
                )
3181
            );
3182
3183
        $emptyValue = self::EMPTY_FIELD_VALUE;
3184
        $fieldTypeMock->expects($this->any())
3185
            ->method('toPersistenceValue')
3186
            ->will(
3187
                $this->returnCallback(
3188
                    function (ValueStub $value) {
3189
                        return (string)$value;
3190
                    }
3191
                )
3192
            );
3193
3194
        $fieldTypeMock->expects($this->any())
3195
            ->method('isEmptyValue')
3196
            ->will(
3197
                $this->returnCallback(
3198
                    function (ValueStub $value) use ($emptyValue) {
3199
                        return $emptyValue === (string)$value;
3200
                    }
3201
                )
3202
            );
3203
3204
        $fieldTypeMock->expects($this->any())
3205
            ->method('validate')
3206
            ->will($this->returnValue([]));
3207
3208
        $this->getFieldTypeRegistryMock()->expects($this->any())
3209
            ->method('getFieldType')
3210
            ->will($this->returnValue($fieldTypeMock));
3211
3212
        $relationProcessorMock
3213
            ->expects($this->exactly(count($fieldDefinitions) * count($languageCodes)))
3214
            ->method('appendFieldRelations')
3215
            ->with(
3216
                $this->isType('array'),
3217
                $this->isType('array'),
3218
                $this->isInstanceOf('eZ\\Publish\\SPI\\FieldType\\FieldType'),
3219
                $this->isInstanceOf('eZ\\Publish\\Core\\FieldType\\Value'),
3220
                $this->anything()
3221
            );
3222
3223
        $values = $this->determineValuesForUpdate(
3224
            $initialLanguageCode,
3225
            $structFields,
3226
            $content,
3227
            $fieldDefinitions,
3228
            $languageCodes
3229
        );
3230
        $nameSchemaServiceMock->expects($this->once())
3231
            ->method('resolveNameSchema')
3232
            ->with(
3233
                $this->equalTo($content),
3234
                $this->equalTo($values),
3235
                $this->equalTo($languageCodes)
3236
            )->will($this->returnValue([]));
3237
3238
        $existingRelations = ['RELATIONS!!!'];
3239
        $mockedService->expects($this->once())
3240
            ->method('loadRelations')
3241
            ->with($content->versionInfo)
3242
            ->will($this->returnValue($existingRelations));
3243
        $relationProcessorMock->expects($this->any())
3244
            ->method('processFieldRelations')
3245
            ->with(
3246
                $this->isType('array'),
3247
                $this->equalTo(42),
3248
                $this->isType('int'),
3249
                $this->equalTo($contentType),
3250
                $this->equalTo($existingRelations)
3251
            );
3252
3253
        $contentUpdateStruct = new ContentUpdateStruct(
3254
            [
3255
                'fields' => $structFields,
3256
                'initialLanguageCode' => $initialLanguageCode,
3257
            ]
3258
        );
3259
3260
        if ($execute) {
3261
            $spiContentUpdateStruct = new SPIContentUpdateStruct(
3262
                [
3263
                    'creatorId' => 169,
3264
                    'fields' => $spiFields,
3265
                    'modificationDate' => time(),
3266
                    'initialLanguageId' => 4242,
3267
                ]
3268
            );
3269
3270
            // During code coverage runs, timestamp might differ 1-3 seconds
3271
            $spiContentUpdateStructTs1 = clone $spiContentUpdateStruct;
3272
            ++$spiContentUpdateStructTs1->modificationDate;
3273
3274
            $spiContentUpdateStructTs2 = clone $spiContentUpdateStructTs1;
3275
            ++$spiContentUpdateStructTs2->modificationDate;
3276
3277
            $spiContentUpdateStructTs3 = clone $spiContentUpdateStructTs2;
3278
            ++$spiContentUpdateStructTs3->modificationDate;
3279
3280
            $spiContent = new SPIContent(
3281
                [
3282
                    'versionInfo' => new SPIContent\VersionInfo(
3283
                        [
3284
                            'contentInfo' => new SPIContent\ContentInfo(['id' => 42]),
3285
                            'versionNo' => 7,
3286
                        ]
3287
                    ),
3288
                ]
3289
            );
3290
3291
            $contentHandlerMock->expects($this->once())
3292
                ->method('updateContent')
3293
                ->with(
3294
                    42,
3295
                    7,
3296
                    $this->logicalOr($spiContentUpdateStruct, $spiContentUpdateStructTs1, $spiContentUpdateStructTs2, $spiContentUpdateStructTs3)
3297
                )
3298
                ->will($this->returnValue($spiContent));
3299
3300
            $repositoryMock->expects($this->once())->method('commit');
3301
            $domainMapperMock->expects($this->once())
3302
                ->method('buildContentDomainObject')
3303
                ->with(
3304
                    $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content'),
3305
                    $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType')
3306
                );
3307
3308
            $mockedService->updateContent($content->versionInfo, $contentUpdateStruct);
3309
        }
3310
3311
        return [$content->versionInfo, $contentUpdateStruct];
3312
    }
3313
3314
    public function providerForTestUpdateContentNonRedundantFieldSet1()
3315
    {
3316
        $spiFields = [
3317
            new SPIField(
3318
                [
3319
                    'id' => '100',
3320
                    'fieldDefinitionId' => 'fieldDefinitionId',
3321
                    'type' => 'fieldTypeIdentifier',
3322
                    'value' => 'newValue',
3323
                    'languageCode' => 'eng-GB',
3324
                    'versionNo' => 7,
3325
                ]
3326
            ),
3327
        ];
3328
3329
        return [
3330
            // With languages set
3331
            [
3332
                'eng-GB',
3333
                [
3334
                    new Field(
3335
                        [
3336
                            'fieldDefIdentifier' => 'identifier',
3337
                            'value' => 'newValue',
3338
                            'languageCode' => 'eng-GB',
3339
                        ]
3340
                    ),
3341
                ],
3342
                $spiFields,
3343
            ],
3344
            // Without languages set
3345
            [
3346
                null,
3347
                [
3348
                    new Field(
3349
                        [
3350
                            'fieldDefIdentifier' => 'identifier',
3351
                            'value' => 'newValue',
3352
                            'languageCode' => null,
3353
                        ]
3354
                    ),
3355
                ],
3356
                $spiFields,
3357
            ],
3358
            // Adding new language without fields
3359
            [
3360
                'eng-US',
3361
                [],
3362
                [],
3363
            ],
3364
        ];
3365
    }
3366
3367
    /**
3368
     * Test for the updateContent() method.
3369
     *
3370
     * Testing the simplest use case.
3371
     *
3372
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
3373
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
3374
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
3375
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSet1
3376
     */
3377 View Code Duplication
    public function testUpdateContentNonRedundantFieldSet1($initialLanguageCode, $structFields, $spiFields)
3378
    {
3379
        $existingFields = [
3380
            new Field(
3381
                [
3382
                    'id' => '100',
3383
                    'fieldDefIdentifier' => 'identifier',
3384
                    'value' => 'initialValue',
3385
                    'languageCode' => 'eng-GB',
3386
                ]
3387
            ),
3388
        ];
3389
3390
        $fieldDefinitions = [
3391
            new FieldDefinition(
3392
                [
3393
                    'id' => 'fieldDefinitionId',
3394
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
3395
                    'isTranslatable' => false,
3396
                    'identifier' => 'identifier',
3397
                    'isRequired' => false,
3398
                    'defaultValue' => 'defaultValue',
3399
                ]
3400
            ),
3401
        ];
3402
3403
        $this->assertForTestUpdateContentNonRedundantFieldSet(
3404
            $initialLanguageCode,
3405
            $structFields,
3406
            $spiFields,
3407
            $existingFields,
3408
            $fieldDefinitions
3409
        );
3410
    }
3411
3412
    public function providerForTestUpdateContentNonRedundantFieldSet2()
3413
    {
3414
        $spiFields0 = [
3415
            new SPIField(
3416
                [
3417
                    'id' => '100',
3418
                    'fieldDefinitionId' => 'fieldDefinitionId',
3419
                    'type' => 'fieldTypeIdentifier',
3420
                    'value' => 'newValue',
3421
                    'languageCode' => 'eng-GB',
3422
                    'versionNo' => 7,
3423
                ]
3424
            ),
3425
        ];
3426
        $spiFields1 = [
3427
            new SPIField(
3428
                [
3429
                    'id' => null,
3430
                    'fieldDefinitionId' => 'fieldDefinitionId',
3431
                    'type' => 'fieldTypeIdentifier',
3432
                    'value' => 'newValue',
3433
                    'languageCode' => 'eng-US',
3434
                    'versionNo' => 7,
3435
                ]
3436
            ),
3437
        ];
3438
        $spiFields2 = [
3439
            new SPIField(
3440
                [
3441
                    'id' => 100,
3442
                    'fieldDefinitionId' => 'fieldDefinitionId',
3443
                    'type' => 'fieldTypeIdentifier',
3444
                    'value' => 'newValue2',
3445
                    'languageCode' => 'eng-GB',
3446
                    'versionNo' => 7,
3447
                ]
3448
            ),
3449
            new SPIField(
3450
                [
3451
                    'id' => null,
3452
                    'fieldDefinitionId' => 'fieldDefinitionId',
3453
                    'type' => 'fieldTypeIdentifier',
3454
                    'value' => 'newValue1',
3455
                    'languageCode' => 'eng-US',
3456
                    'versionNo' => 7,
3457
                ]
3458
            ),
3459
        ];
3460
3461
        return [
3462
            // 0. With languages set
3463
            [
3464
                'eng-GB',
3465
                [
3466
                    new Field(
3467
                        [
3468
                            'fieldDefIdentifier' => 'identifier',
3469
                            'value' => 'newValue',
3470
                            'languageCode' => 'eng-GB',
3471
                        ]
3472
                    ),
3473
                ],
3474
                $spiFields0,
3475
            ],
3476
            // 1. Without languages set
3477
            [
3478
                null,
3479
                [
3480
                    new Field(
3481
                        [
3482
                            'fieldDefIdentifier' => 'identifier',
3483
                            'value' => 'newValue',
3484
                            'languageCode' => null,
3485
                        ]
3486
                    ),
3487
                ],
3488
                $spiFields0,
3489
            ],
3490
            // 2. New language with language set
3491
            [
3492
                'eng-GB',
3493
                [
3494
                    new Field(
3495
                        [
3496
                            'fieldDefIdentifier' => 'identifier',
3497
                            'value' => 'newValue',
3498
                            'languageCode' => 'eng-US',
3499
                        ]
3500
                    ),
3501
                ],
3502
                $spiFields1,
3503
            ],
3504
            // 3. New language without language set
3505
            [
3506
                'eng-US',
3507
                [
3508
                    new Field(
3509
                        [
3510
                            'fieldDefIdentifier' => 'identifier',
3511
                            'value' => 'newValue',
3512
                            'languageCode' => null,
3513
                        ]
3514
                    ),
3515
                ],
3516
                $spiFields1,
3517
            ],
3518
            // 4. New language and existing language with language set
3519
            [
3520
                'eng-GB',
3521
                [
3522
                    new Field(
3523
                        [
3524
                            'fieldDefIdentifier' => 'identifier',
3525
                            'value' => 'newValue1',
3526
                            'languageCode' => 'eng-US',
3527
                        ]
3528
                    ),
3529
                    new Field(
3530
                        [
3531
                            'fieldDefIdentifier' => 'identifier',
3532
                            'value' => 'newValue2',
3533
                            'languageCode' => 'eng-GB',
3534
                        ]
3535
                    ),
3536
                ],
3537
                $spiFields2,
3538
            ],
3539
            // 5. New language and existing language without language set
3540
            [
3541
                'eng-US',
3542
                [
3543
                    new Field(
3544
                        [
3545
                            'fieldDefIdentifier' => 'identifier',
3546
                            'value' => 'newValue1',
3547
                            'languageCode' => null,
3548
                        ]
3549
                    ),
3550
                    new Field(
3551
                        [
3552
                            'fieldDefIdentifier' => 'identifier',
3553
                            'value' => 'newValue2',
3554
                            'languageCode' => 'eng-GB',
3555
                        ]
3556
                    ),
3557
                ],
3558
                $spiFields2,
3559
            ],
3560
            // 6. Adding new language without fields
3561
            [
3562
                'eng-US',
3563
                [],
3564
                [
3565
                    new SPIField(
3566
                        [
3567
                            'id' => null,
3568
                            'fieldDefinitionId' => 'fieldDefinitionId',
3569
                            'type' => 'fieldTypeIdentifier',
3570
                            'value' => 'defaultValue',
3571
                            'languageCode' => 'eng-US',
3572
                            'versionNo' => 7,
3573
                        ]
3574
                    ),
3575
                ],
3576
            ],
3577
        ];
3578
    }
3579
3580
    /**
3581
     * Test for the updateContent() method.
3582
     *
3583
     * Testing with translatable field.
3584
     *
3585
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
3586
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
3587
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
3588
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSet2
3589
     */
3590 View Code Duplication
    public function testUpdateContentNonRedundantFieldSet2($initialLanguageCode, $structFields, $spiFields)
3591
    {
3592
        $existingFields = [
3593
            new Field(
3594
                [
3595
                    'id' => '100',
3596
                    'fieldDefIdentifier' => 'identifier',
3597
                    'value' => 'initialValue',
3598
                    'languageCode' => 'eng-GB',
3599
                ]
3600
            ),
3601
        ];
3602
3603
        $fieldDefinitions = [
3604
            new FieldDefinition(
3605
                [
3606
                    'id' => 'fieldDefinitionId',
3607
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
3608
                    'isTranslatable' => true,
3609
                    'identifier' => 'identifier',
3610
                    'isRequired' => false,
3611
                    'defaultValue' => 'defaultValue',
3612
                ]
3613
            ),
3614
        ];
3615
3616
        $this->assertForTestUpdateContentNonRedundantFieldSet(
3617
            $initialLanguageCode,
3618
            $structFields,
3619
            $spiFields,
3620
            $existingFields,
3621
            $fieldDefinitions
3622
        );
3623
    }
3624
3625
    public function providerForTestUpdateContentNonRedundantFieldSet3()
3626
    {
3627
        $spiFields0 = [
3628
            new SPIField(
3629
                [
3630
                    'id' => null,
3631
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3632
                    'type' => 'fieldTypeIdentifier',
3633
                    'value' => 'newValue1',
3634
                    'languageCode' => 'eng-US',
3635
                    'versionNo' => 7,
3636
                ]
3637
            ),
3638
        ];
3639
        $spiFields1 = [
3640
            new SPIField(
3641
                [
3642
                    'id' => 100,
3643
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3644
                    'type' => 'fieldTypeIdentifier',
3645
                    'value' => 'newValue2',
3646
                    'languageCode' => 'eng-GB',
3647
                    'versionNo' => 7,
3648
                ]
3649
            ),
3650
            new SPIField(
3651
                [
3652
                    'id' => null,
3653
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3654
                    'type' => 'fieldTypeIdentifier',
3655
                    'value' => 'newValue1',
3656
                    'languageCode' => 'eng-US',
3657
                    'versionNo' => 7,
3658
                ]
3659
            ),
3660
        ];
3661
        $spiFields2 = [
3662
            new SPIField(
3663
                [
3664
                    'id' => 100,
3665
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3666
                    'type' => 'fieldTypeIdentifier',
3667
                    'value' => 'newValue2',
3668
                    'languageCode' => 'eng-GB',
3669
                    'versionNo' => 7,
3670
                ]
3671
            ),
3672
            new SPIField(
3673
                [
3674
                    'id' => null,
3675
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3676
                    'type' => 'fieldTypeIdentifier',
3677
                    'value' => 'newValue1',
3678
                    'languageCode' => 'eng-US',
3679
                    'versionNo' => 7,
3680
                ]
3681
            ),
3682
            new SPIField(
3683
                [
3684
                    'id' => 101,
3685
                    'fieldDefinitionId' => 'fieldDefinitionId2',
3686
                    'type' => 'fieldTypeIdentifier',
3687
                    'value' => 'newValue3',
3688
                    'languageCode' => 'eng-GB',
3689
                    'versionNo' => 7,
3690
                ]
3691
            ),
3692
        ];
3693
        $spiFields3 = [
3694
            new SPIField(
3695
                [
3696
                    'id' => null,
3697
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3698
                    'type' => 'fieldTypeIdentifier',
3699
                    'value' => 'defaultValue1',
3700
                    'languageCode' => 'eng-US',
3701
                    'versionNo' => 7,
3702
                ]
3703
            ),
3704
        ];
3705
3706
        return [
3707
            // 0. ew language with language set
3708
            [
3709
                'eng-US',
3710
                [
3711
                    new Field(
3712
                        [
3713
                            'fieldDefIdentifier' => 'identifier1',
3714
                            'value' => 'newValue1',
3715
                            'languageCode' => 'eng-US',
3716
                        ]
3717
                    ),
3718
                ],
3719
                $spiFields0,
3720
            ],
3721
            // 1. New language without language set
3722
            [
3723
                'eng-US',
3724
                [
3725
                    new Field(
3726
                        [
3727
                            'fieldDefIdentifier' => 'identifier1',
3728
                            'value' => 'newValue1',
3729
                            'languageCode' => null,
3730
                        ]
3731
                    ),
3732
                ],
3733
                $spiFields0,
3734
            ],
3735
            // 2. New language and existing language with language set
3736
            [
3737
                'eng-US',
3738
                [
3739
                    new Field(
3740
                        [
3741
                            'fieldDefIdentifier' => 'identifier1',
3742
                            'value' => 'newValue1',
3743
                            'languageCode' => 'eng-US',
3744
                        ]
3745
                    ),
3746
                    new Field(
3747
                        [
3748
                            'fieldDefIdentifier' => 'identifier1',
3749
                            'value' => 'newValue2',
3750
                            'languageCode' => 'eng-GB',
3751
                        ]
3752
                    ),
3753
                ],
3754
                $spiFields1,
3755
            ],
3756
            // 3. New language and existing language without language set
3757
            [
3758
                'eng-US',
3759
                [
3760
                    new Field(
3761
                        [
3762
                            'fieldDefIdentifier' => 'identifier1',
3763
                            'value' => 'newValue1',
3764
                            'languageCode' => null,
3765
                        ]
3766
                    ),
3767
                    new Field(
3768
                        [
3769
                            'fieldDefIdentifier' => 'identifier1',
3770
                            'value' => 'newValue2',
3771
                            'languageCode' => 'eng-GB',
3772
                        ]
3773
                    ),
3774
                ],
3775
                $spiFields1,
3776
            ],
3777
            // 4. New language and existing language with untranslatable field, with language set
3778
            [
3779
                'eng-US',
3780
                [
3781
                    new Field(
3782
                        [
3783
                            'fieldDefIdentifier' => 'identifier1',
3784
                            'value' => 'newValue1',
3785
                            'languageCode' => 'eng-US',
3786
                        ]
3787
                    ),
3788
                    new Field(
3789
                        [
3790
                            'fieldDefIdentifier' => 'identifier1',
3791
                            'value' => 'newValue2',
3792
                            'languageCode' => 'eng-GB',
3793
                        ]
3794
                    ),
3795
                    new Field(
3796
                        [
3797
                            'fieldDefIdentifier' => 'identifier2',
3798
                            'value' => 'newValue3',
3799
                            'languageCode' => 'eng-GB',
3800
                        ]
3801
                    ),
3802
                ],
3803
                $spiFields2,
3804
            ],
3805
            // 5. New language and existing language with untranslatable field, without language set
3806
            [
3807
                'eng-US',
3808
                [
3809
                    new Field(
3810
                        [
3811
                            'fieldDefIdentifier' => 'identifier1',
3812
                            'value' => 'newValue1',
3813
                            'languageCode' => null,
3814
                        ]
3815
                    ),
3816
                    new Field(
3817
                        [
3818
                            'fieldDefIdentifier' => 'identifier1',
3819
                            'value' => 'newValue2',
3820
                            'languageCode' => 'eng-GB',
3821
                        ]
3822
                    ),
3823
                    new Field(
3824
                        [
3825
                            'fieldDefIdentifier' => 'identifier2',
3826
                            'value' => 'newValue3',
3827
                            'languageCode' => null,
3828
                        ]
3829
                    ),
3830
                ],
3831
                $spiFields2,
3832
            ],
3833
            // 6. Adding new language without fields
3834
            [
3835
                'eng-US',
3836
                [],
3837
                $spiFields3,
3838
            ],
3839
        ];
3840
    }
3841
3842
    /**
3843
     * Test for the updateContent() method.
3844
     *
3845
     * Testing with new language and untranslatable field.
3846
     *
3847
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
3848
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
3849
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
3850
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSet3
3851
     */
3852
    public function testUpdateContentNonRedundantFieldSet3($initialLanguageCode, $structFields, $spiFields)
3853
    {
3854
        $existingFields = [
3855
            new Field(
3856
                [
3857
                    'id' => '100',
3858
                    'fieldDefIdentifier' => 'identifier1',
3859
                    'value' => 'initialValue1',
3860
                    'languageCode' => 'eng-GB',
3861
                ]
3862
            ),
3863
            new Field(
3864
                [
3865
                    'id' => '101',
3866
                    'fieldDefIdentifier' => 'identifier2',
3867
                    'value' => 'initialValue2',
3868
                    'languageCode' => 'eng-GB',
3869
                ]
3870
            ),
3871
        ];
3872
3873
        $fieldDefinitions = [
3874
            new FieldDefinition(
3875
                [
3876
                    'id' => 'fieldDefinitionId1',
3877
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
3878
                    'isTranslatable' => true,
3879
                    'identifier' => 'identifier1',
3880
                    'isRequired' => false,
3881
                    'defaultValue' => 'defaultValue1',
3882
                ]
3883
            ),
3884
            new FieldDefinition(
3885
                [
3886
                    'id' => 'fieldDefinitionId2',
3887
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
3888
                    'isTranslatable' => false,
3889
                    'identifier' => 'identifier2',
3890
                    'isRequired' => false,
3891
                    'defaultValue' => 'defaultValue2',
3892
                ]
3893
            ),
3894
        ];
3895
3896
        $this->assertForTestUpdateContentNonRedundantFieldSet(
3897
            $initialLanguageCode,
3898
            $structFields,
3899
            $spiFields,
3900
            $existingFields,
3901
            $fieldDefinitions
3902
        );
3903
    }
3904
3905
    public function providerForTestUpdateContentNonRedundantFieldSet4()
3906
    {
3907
        $spiFields0 = [
3908
            new SPIField(
3909
                [
3910
                    'id' => null,
3911
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3912
                    'type' => 'fieldTypeIdentifier',
3913
                    'value' => 'newValue1',
3914
                    'languageCode' => 'eng-US',
3915
                    'versionNo' => 7,
3916
                ]
3917
            ),
3918
        ];
3919
        $spiFields1 = [
3920
            new SPIField(
3921
                [
3922
                    'id' => 100,
3923
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3924
                    'type' => 'fieldTypeIdentifier',
3925
                    'value' => self::EMPTY_FIELD_VALUE,
3926
                    'languageCode' => 'eng-GB',
3927
                    'versionNo' => 7,
3928
                ]
3929
            ),
3930
            new SPIField(
3931
                [
3932
                    'id' => null,
3933
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3934
                    'type' => 'fieldTypeIdentifier',
3935
                    'value' => 'newValue1',
3936
                    'languageCode' => 'eng-US',
3937
                    'versionNo' => 7,
3938
                ]
3939
            ),
3940
        ];
3941
        $spiFields2 = [
3942
            new SPIField(
3943
                [
3944
                    'id' => 100,
3945
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3946
                    'type' => 'fieldTypeIdentifier',
3947
                    'value' => self::EMPTY_FIELD_VALUE,
3948
                    'languageCode' => 'eng-GB',
3949
                    'versionNo' => 7,
3950
                ]
3951
            ),
3952
        ];
3953
3954
        return [
3955
            // 0. New translation with empty field by default
3956
            [
3957
                'eng-US',
3958
                [
3959
                    new Field(
3960
                        [
3961
                            'fieldDefIdentifier' => 'identifier1',
3962
                            'value' => 'newValue1',
3963
                            'languageCode' => 'eng-US',
3964
                        ]
3965
                    ),
3966
                ],
3967
                $spiFields0,
3968
            ],
3969
            // 1. New translation with empty field by default, without language set
3970
            [
3971
                'eng-US',
3972
                [
3973
                    new Field(
3974
                        [
3975
                            'fieldDefIdentifier' => 'identifier1',
3976
                            'value' => 'newValue1',
3977
                            'languageCode' => null,
3978
                        ]
3979
                    ),
3980
                ],
3981
                $spiFields0,
3982
            ],
3983
            // 2. New translation with empty field given
3984
            [
3985
                'eng-US',
3986
                [
3987
                    new Field(
3988
                        [
3989
                            'fieldDefIdentifier' => 'identifier1',
3990
                            'value' => 'newValue1',
3991
                            'languageCode' => 'eng-US',
3992
                        ]
3993
                    ),
3994
                    new Field(
3995
                        [
3996
                            'fieldDefIdentifier' => 'identifier2',
3997
                            'value' => self::EMPTY_FIELD_VALUE,
3998
                            'languageCode' => 'eng-US',
3999
                        ]
4000
                    ),
4001
                ],
4002
                $spiFields0,
4003
            ],
4004
            // 3. New translation with empty field given, without language set
4005
            [
4006
                'eng-US',
4007
                [
4008
                    new Field(
4009
                        [
4010
                            'fieldDefIdentifier' => 'identifier1',
4011
                            'value' => 'newValue1',
4012
                            'languageCode' => null,
4013
                        ]
4014
                    ),
4015
                    new Field(
4016
                        [
4017
                            'fieldDefIdentifier' => 'identifier2',
4018
                            'value' => self::EMPTY_FIELD_VALUE,
4019
                            'languageCode' => null,
4020
                        ]
4021
                    ),
4022
                ],
4023
                $spiFields0,
4024
            ],
4025
            // 4. Updating existing language with empty value
4026
            [
4027
                'eng-US',
4028
                [
4029
                    new Field(
4030
                        [
4031
                            'fieldDefIdentifier' => 'identifier1',
4032
                            'value' => 'newValue1',
4033
                            'languageCode' => 'eng-US',
4034
                        ]
4035
                    ),
4036
                    new Field(
4037
                        [
4038
                            'fieldDefIdentifier' => 'identifier1',
4039
                            'value' => self::EMPTY_FIELD_VALUE,
4040
                            'languageCode' => 'eng-GB',
4041
                        ]
4042
                    ),
4043
                ],
4044
                $spiFields1,
4045
            ],
4046
            // 5. Updating existing language with empty value, without language set
4047
            [
4048
                'eng-US',
4049
                [
4050
                    new Field(
4051
                        [
4052
                            'fieldDefIdentifier' => 'identifier1',
4053
                            'value' => 'newValue1',
4054
                            'languageCode' => null,
4055
                        ]
4056
                    ),
4057
                    new Field(
4058
                        [
4059
                            'fieldDefIdentifier' => 'identifier1',
4060
                            'value' => self::EMPTY_FIELD_VALUE,
4061
                            'languageCode' => 'eng-GB',
4062
                        ]
4063
                    ),
4064
                ],
4065
                $spiFields1,
4066
            ],
4067
            // 6. Updating existing language with empty value and adding new language with empty value
4068
            [
4069
                'eng-US',
4070
                [
4071
                    new Field(
4072
                        [
4073
                            'fieldDefIdentifier' => 'identifier1',
4074
                            'value' => self::EMPTY_FIELD_VALUE,
4075
                            'languageCode' => 'eng-US',
4076
                        ]
4077
                    ),
4078
                    new Field(
4079
                        [
4080
                            'fieldDefIdentifier' => 'identifier1',
4081
                            'value' => self::EMPTY_FIELD_VALUE,
4082
                            'languageCode' => 'eng-GB',
4083
                        ]
4084
                    ),
4085
                ],
4086
                $spiFields2,
4087
            ],
4088
            // 7. Updating existing language with empty value and adding new language with empty value,
4089
            // without language set
4090
            [
4091
                'eng-US',
4092
                [
4093
                    new Field(
4094
                        [
4095
                            'fieldDefIdentifier' => 'identifier1',
4096
                            'value' => self::EMPTY_FIELD_VALUE,
4097
                            'languageCode' => null,
4098
                        ]
4099
                    ),
4100
                    new Field(
4101
                        [
4102
                            'fieldDefIdentifier' => 'identifier1',
4103
                            'value' => self::EMPTY_FIELD_VALUE,
4104
                            'languageCode' => 'eng-GB',
4105
                        ]
4106
                    ),
4107
                ],
4108
                $spiFields2,
4109
            ],
4110
            // 8. Adding new language with no fields given
4111
            [
4112
                'eng-US',
4113
                [],
4114
                [],
4115
            ],
4116
            // 9. Adding new language with fields
4117
            [
4118
                'eng-US',
4119
                [
4120
                    new Field(
4121
                        [
4122
                            'fieldDefIdentifier' => 'identifier1',
4123
                            'value' => self::EMPTY_FIELD_VALUE,
4124
                            'languageCode' => 'eng-US',
4125
                        ]
4126
                    ),
4127
                ],
4128
                [],
4129
            ],
4130
            // 10. Adding new language with fields, without language set
4131
            [
4132
                'eng-US',
4133
                [
4134
                    new Field(
4135
                        [
4136
                            'fieldDefIdentifier' => 'identifier1',
4137
                            'value' => self::EMPTY_FIELD_VALUE,
4138
                            'languageCode' => null,
4139
                        ]
4140
                    ),
4141
                ],
4142
                [],
4143
            ],
4144
        ];
4145
    }
4146
4147
    /**
4148
     * Test for the updateContent() method.
4149
     *
4150
     * Testing with empty values.
4151
     *
4152
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4153
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4154
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4155
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSet4
4156
     */
4157
    public function testUpdateContentNonRedundantFieldSet4($initialLanguageCode, $structFields, $spiFields)
4158
    {
4159
        $existingFields = [
4160
            new Field(
4161
                [
4162
                    'id' => '100',
4163
                    'fieldDefIdentifier' => 'identifier1',
4164
                    'value' => 'initialValue1',
4165
                    'languageCode' => 'eng-GB',
4166
                ]
4167
            ),
4168
            new Field(
4169
                [
4170
                    'id' => '101',
4171
                    'fieldDefIdentifier' => 'identifier2',
4172
                    'value' => 'initialValue2',
4173
                    'languageCode' => 'eng-GB',
4174
                ]
4175
            ),
4176
        ];
4177
4178
        $fieldDefinitions = [
4179
            new FieldDefinition(
4180
                [
4181
                    'id' => 'fieldDefinitionId1',
4182
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4183
                    'isTranslatable' => true,
4184
                    'identifier' => 'identifier1',
4185
                    'isRequired' => false,
4186
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4187
                ]
4188
            ),
4189
            new FieldDefinition(
4190
                [
4191
                    'id' => 'fieldDefinitionId2',
4192
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4193
                    'isTranslatable' => true,
4194
                    'identifier' => 'identifier2',
4195
                    'isRequired' => false,
4196
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4197
                ]
4198
            ),
4199
        ];
4200
4201
        $this->assertForTestUpdateContentNonRedundantFieldSet(
4202
            $initialLanguageCode,
4203
            $structFields,
4204
            $spiFields,
4205
            $existingFields,
4206
            $fieldDefinitions
4207
        );
4208
    }
4209
4210
    /**
4211
     * @todo add first field empty
4212
     *
4213
     * @return array
4214
     */
4215
    public function providerForTestUpdateContentNonRedundantFieldSetComplex()
4216
    {
4217
        $spiFields0 = [
4218
            new SPIField(
4219
                [
4220
                    'id' => 100,
4221
                    'fieldDefinitionId' => 'fieldDefinitionId1',
4222
                    'type' => 'fieldTypeIdentifier',
4223
                    'value' => 'newValue1-eng-GB',
4224
                    'languageCode' => 'eng-GB',
4225
                    'versionNo' => 7,
4226
                ]
4227
            ),
4228
            new SPIField(
4229
                [
4230
                    'id' => null,
4231
                    'fieldDefinitionId' => 'fieldDefinitionId4',
4232
                    'type' => 'fieldTypeIdentifier',
4233
                    'value' => 'newValue4',
4234
                    'languageCode' => 'eng-US',
4235
                    'versionNo' => 7,
4236
                ]
4237
            ),
4238
        ];
4239
        $spiFields1 = [
4240
            new SPIField(
4241
                [
4242
                    'id' => 100,
4243
                    'fieldDefinitionId' => 'fieldDefinitionId1',
4244
                    'type' => 'fieldTypeIdentifier',
4245
                    'value' => 'newValue1-eng-GB',
4246
                    'languageCode' => 'eng-GB',
4247
                    'versionNo' => 7,
4248
                ]
4249
            ),
4250
            new SPIField(
4251
                [
4252
                    'id' => null,
4253
                    'fieldDefinitionId' => 'fieldDefinitionId2',
4254
                    'type' => 'fieldTypeIdentifier',
4255
                    'value' => 'newValue2',
4256
                    'languageCode' => 'eng-US',
4257
                    'versionNo' => 7,
4258
                ]
4259
            ),
4260
            new SPIField(
4261
                [
4262
                    'id' => null,
4263
                    'fieldDefinitionId' => 'fieldDefinitionId4',
4264
                    'type' => 'fieldTypeIdentifier',
4265
                    'value' => 'defaultValue4',
4266
                    'languageCode' => 'eng-US',
4267
                    'versionNo' => 7,
4268
                ]
4269
            ),
4270
        ];
4271
        $spiFields2 = [
4272
            new SPIField(
4273
                [
4274
                    'id' => 100,
4275
                    'fieldDefinitionId' => 'fieldDefinitionId1',
4276
                    'type' => 'fieldTypeIdentifier',
4277
                    'value' => 'newValue1-eng-GB',
4278
                    'languageCode' => 'eng-GB',
4279
                    'versionNo' => 7,
4280
                ]
4281
            ),
4282
            new SPIField(
4283
                [
4284
                    'id' => null,
4285
                    'fieldDefinitionId' => 'fieldDefinitionId2',
4286
                    'type' => 'fieldTypeIdentifier',
4287
                    'value' => 'newValue2',
4288
                    'languageCode' => 'eng-US',
4289
                    'versionNo' => 7,
4290
                ]
4291
            ),
4292
            new SPIField(
4293
                [
4294
                    'id' => null,
4295
                    'fieldDefinitionId' => 'fieldDefinitionId4',
4296
                    'type' => 'fieldTypeIdentifier',
4297
                    'value' => 'defaultValue4',
4298
                    'languageCode' => 'ger-DE',
4299
                    'versionNo' => 7,
4300
                ]
4301
            ),
4302
            new SPIField(
4303
                [
4304
                    'id' => null,
4305
                    'fieldDefinitionId' => 'fieldDefinitionId4',
4306
                    'type' => 'fieldTypeIdentifier',
4307
                    'value' => 'defaultValue4',
4308
                    'languageCode' => 'eng-US',
4309
                    'versionNo' => 7,
4310
                ]
4311
            ),
4312
        ];
4313
4314
        return [
4315
            // 0. Add new language and update existing
4316
            [
4317
                'eng-US',
4318
                [
4319
                    new Field(
4320
                        [
4321
                            'fieldDefIdentifier' => 'identifier4',
4322
                            'value' => 'newValue4',
4323
                            'languageCode' => 'eng-US',
4324
                        ]
4325
                    ),
4326
                    new Field(
4327
                        [
4328
                            'fieldDefIdentifier' => 'identifier1',
4329
                            'value' => 'newValue1-eng-GB',
4330
                            'languageCode' => 'eng-GB',
4331
                        ]
4332
                    ),
4333
                ],
4334
                $spiFields0,
4335
            ],
4336
            // 1. Add new language and update existing, without language set
4337
            [
4338
                'eng-US',
4339
                [
4340
                    new Field(
4341
                        [
4342
                            'fieldDefIdentifier' => 'identifier4',
4343
                            'value' => 'newValue4',
4344
                            'languageCode' => null,
4345
                        ]
4346
                    ),
4347
                    new Field(
4348
                        [
4349
                            'fieldDefIdentifier' => 'identifier1',
4350
                            'value' => 'newValue1-eng-GB',
4351
                            'languageCode' => 'eng-GB',
4352
                        ]
4353
                    ),
4354
                ],
4355
                $spiFields0,
4356
            ],
4357
            // 2. Add new language and update existing variant
4358
            [
4359
                'eng-US',
4360
                [
4361
                    new Field(
4362
                        [
4363
                            'fieldDefIdentifier' => 'identifier2',
4364
                            'value' => 'newValue2',
4365
                            'languageCode' => 'eng-US',
4366
                        ]
4367
                    ),
4368
                    new Field(
4369
                        [
4370
                            'fieldDefIdentifier' => 'identifier1',
4371
                            'value' => 'newValue1-eng-GB',
4372
                            'languageCode' => 'eng-GB',
4373
                        ]
4374
                    ),
4375
                ],
4376
                $spiFields1,
4377
            ],
4378
            // 3. Add new language and update existing variant, without language set
4379
            [
4380
                'eng-US',
4381
                [
4382
                    new Field(
4383
                        [
4384
                            'fieldDefIdentifier' => 'identifier2',
4385
                            'value' => 'newValue2',
4386
                            'languageCode' => null,
4387
                        ]
4388
                    ),
4389
                    new Field(
4390
                        [
4391
                            'fieldDefIdentifier' => 'identifier1',
4392
                            'value' => 'newValue1-eng-GB',
4393
                            'languageCode' => 'eng-GB',
4394
                        ]
4395
                    ),
4396
                ],
4397
                $spiFields1,
4398
            ],
4399
            // 4. Update with multiple languages
4400
            [
4401
                'ger-DE',
4402
                [
4403
                    new Field(
4404
                        [
4405
                            'fieldDefIdentifier' => 'identifier2',
4406
                            'value' => 'newValue2',
4407
                            'languageCode' => 'eng-US',
4408
                        ]
4409
                    ),
4410
                    new Field(
4411
                        [
4412
                            'fieldDefIdentifier' => 'identifier1',
4413
                            'value' => 'newValue1-eng-GB',
4414
                            'languageCode' => 'eng-GB',
4415
                        ]
4416
                    ),
4417
                ],
4418
                $spiFields2,
4419
            ],
4420
            // 5. Update with multiple languages without language set
4421
            [
4422
                'ger-DE',
4423
                [
4424
                    new Field(
4425
                        [
4426
                            'fieldDefIdentifier' => 'identifier2',
4427
                            'value' => 'newValue2',
4428
                            'languageCode' => 'eng-US',
4429
                        ]
4430
                    ),
4431
                    new Field(
4432
                        [
4433
                            'fieldDefIdentifier' => 'identifier1',
4434
                            'value' => 'newValue1-eng-GB',
4435
                            'languageCode' => null,
4436
                        ]
4437
                    ),
4438
                ],
4439
                $spiFields2,
4440
            ],
4441
        ];
4442
    }
4443
4444
    protected function fixturesForTestUpdateContentNonRedundantFieldSetComplex()
4445
    {
4446
        $existingFields = [
4447
            new Field(
4448
                [
4449
                    'id' => '100',
4450
                    'fieldDefIdentifier' => 'identifier1',
4451
                    'value' => 'initialValue1',
4452
                    'languageCode' => 'eng-GB',
4453
                ]
4454
            ),
4455
            new Field(
4456
                [
4457
                    'id' => '101',
4458
                    'fieldDefIdentifier' => 'identifier2',
4459
                    'value' => 'initialValue2',
4460
                    'languageCode' => 'eng-GB',
4461
                ]
4462
            ),
4463
            new Field(
4464
                [
4465
                    'id' => '102',
4466
                    'fieldDefIdentifier' => 'identifier3',
4467
                    'value' => 'initialValue3',
4468
                    'languageCode' => 'eng-GB',
4469
                ]
4470
            ),
4471
            new Field(
4472
                [
4473
                    'id' => '103',
4474
                    'fieldDefIdentifier' => 'identifier4',
4475
                    'value' => 'initialValue4',
4476
                    'languageCode' => 'eng-GB',
4477
                ]
4478
            ),
4479
        ];
4480
4481
        $fieldDefinitions = [
4482
            new FieldDefinition(
4483
                [
4484
                    'id' => 'fieldDefinitionId1',
4485
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4486
                    'isTranslatable' => false,
4487
                    'identifier' => 'identifier1',
4488
                    'isRequired' => false,
4489
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4490
                ]
4491
            ),
4492
            new FieldDefinition(
4493
                [
4494
                    'id' => 'fieldDefinitionId2',
4495
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4496
                    'isTranslatable' => true,
4497
                    'identifier' => 'identifier2',
4498
                    'isRequired' => false,
4499
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4500
                ]
4501
            ),
4502
            new FieldDefinition(
4503
                [
4504
                    'id' => 'fieldDefinitionId3',
4505
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4506
                    'isTranslatable' => false,
4507
                    'identifier' => 'identifier3',
4508
                    'isRequired' => false,
4509
                    'defaultValue' => 'defaultValue3',
4510
                ]
4511
            ),
4512
            new FieldDefinition(
4513
                [
4514
                    'id' => 'fieldDefinitionId4',
4515
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4516
                    'isTranslatable' => true,
4517
                    'identifier' => 'identifier4',
4518
                    'isRequired' => false,
4519
                    'defaultValue' => 'defaultValue4',
4520
                ]
4521
            ),
4522
        ];
4523
4524
        return [$existingFields, $fieldDefinitions];
4525
    }
4526
4527
    /**
4528
     * Test for the updateContent() method.
4529
     *
4530
     * Testing more complex cases.
4531
     *
4532
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4533
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4534
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4535
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSetComplex
4536
     */
4537
    public function testUpdateContentNonRedundantFieldSetComplex($initialLanguageCode, $structFields, $spiFields)
4538
    {
4539
        list($existingFields, $fieldDefinitions) = $this->fixturesForTestUpdateContentNonRedundantFieldSetComplex();
4540
4541
        $this->assertForTestUpdateContentNonRedundantFieldSet(
4542
            $initialLanguageCode,
4543
            $structFields,
4544
            $spiFields,
4545
            $existingFields,
4546
            $fieldDefinitions
4547
        );
4548
    }
4549
4550 View Code Duplication
    public function providerForTestUpdateContentWithInvalidLanguage()
4551
    {
4552
        return [
4553
            [
4554
                'eng-GB',
4555
                [
4556
                    new Field(
4557
                        [
4558
                            'fieldDefIdentifier' => 'identifier',
4559
                            'value' => 'newValue',
4560
                            'languageCode' => 'Klingon',
4561
                        ]
4562
                    ),
4563
                ],
4564
            ],
4565
            [
4566
                'Klingon',
4567
                [
4568
                    new Field(
4569
                        [
4570
                            'fieldDefIdentifier' => 'identifier',
4571
                            'value' => 'newValue',
4572
                            'languageCode' => 'eng-GB',
4573
                        ]
4574
                    ),
4575
                ],
4576
            ],
4577
        ];
4578
    }
4579
4580
    /**
4581
     * Test for the updateContent() method.
4582
     *
4583
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4584
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4585
     * @dataProvider providerForTestUpdateContentWithInvalidLanguage
4586
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
4587
     * @expectedExceptionMessage Could not find 'Language' with identifier 'Klingon'
4588
     */
4589
    public function testUpdateContentWithInvalidLanguage($initialLanguageCode, $structFields)
4590
    {
4591
        $repositoryMock = $this->getRepositoryMock();
4592
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
4593
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
4594
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
4595
        $versionInfo = new VersionInfo(
4596
            [
4597
                'contentInfo' => new ContentInfo(
4598
                    [
4599
                        'id' => 42,
4600
                        'contentTypeId' => 24,
4601
                        'mainLanguageCode' => 'eng-GB',
4602
                    ]
4603
                ),
4604
                'versionNo' => 7,
4605
                'languageCodes' => ['eng-GB'],
4606
                'status' => VersionInfo::STATUS_DRAFT,
4607
            ]
4608
        );
4609
        $content = new Content(
4610
            [
4611
                'versionInfo' => $versionInfo,
4612
                'internalFields' => [],
4613
            ]
4614
        );
4615
4616
        $languageHandlerMock->expects($this->any())
4617
            ->method('loadByLanguageCode')
4618
            ->with($this->isType('string'))
4619
            ->will(
4620
                $this->returnCallback(
4621 View Code Duplication
                    function ($languageCode) {
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...
4622
                        if ($languageCode === 'Klingon') {
4623
                            throw new NotFoundException('Language', 'Klingon');
4624
                        }
4625
4626
                        return new Language(['id' => 4242]);
4627
                    }
4628
                )
4629
            );
4630
4631
        $mockedService->expects($this->once())
4632
            ->method('loadContent')
4633
            ->with(
4634
                $this->equalTo(42),
4635
                $this->equalTo(null),
4636
                $this->equalTo(7)
4637
            )->will(
4638
                $this->returnValue($content)
4639
            );
4640
4641
        $repositoryMock->expects($this->once())
4642
            ->method('canUser')
4643
            ->with(
4644
                $this->equalTo('content'),
4645
                $this->equalTo('edit'),
4646
                $this->equalTo($content)
4647
            )->will($this->returnValue(true));
4648
4649
        $contentUpdateStruct = new ContentUpdateStruct(
4650
            [
4651
                'fields' => $structFields,
4652
                'initialLanguageCode' => $initialLanguageCode,
4653
            ]
4654
        );
4655
4656
        $mockedService->updateContent($content->versionInfo, $contentUpdateStruct);
4657
    }
4658
4659
    protected function assertForUpdateContentContentValidationException(
4660
        $initialLanguageCode,
4661
        $structFields,
4662
        $fieldDefinitions = []
4663
    ) {
4664
        $repositoryMock = $this->getRepositoryMock();
4665
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
4666
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
4667
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
4668
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
4669
        $versionInfo = new VersionInfo(
4670
            [
4671
                'contentInfo' => new ContentInfo(
4672
                    [
4673
                        'id' => 42,
4674
                        'contentTypeId' => 24,
4675
                        'mainLanguageCode' => 'eng-GB',
4676
                    ]
4677
                ),
4678
                'versionNo' => 7,
4679
                'languageCodes' => ['eng-GB'],
4680
                'status' => VersionInfo::STATUS_DRAFT,
4681
            ]
4682
        );
4683
        $content = new Content(
4684
            [
4685
                'versionInfo' => $versionInfo,
4686
                'internalFields' => [],
4687
            ]
4688
        );
4689
        $contentType = new ContentType(['fieldDefinitions' => $fieldDefinitions]);
4690
4691
        $languageHandlerMock->expects($this->any())
4692
            ->method('loadByLanguageCode')
4693
            ->with($this->isType('string'))
4694
            ->will(
4695
                $this->returnCallback(
4696 View Code Duplication
                    function ($languageCode) {
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...
4697
                        if ($languageCode === 'Klingon') {
4698
                            throw new NotFoundException('Language', 'Klingon');
4699
                        }
4700
4701
                        return new Language(['id' => 4242]);
4702
                    }
4703
                )
4704
            );
4705
4706
        $mockedService->expects($this->once())
4707
            ->method('loadContent')
4708
            ->with(
4709
                $this->equalTo(42),
4710
                $this->equalTo(null),
4711
                $this->equalTo(7)
4712
            )->will(
4713
                $this->returnValue($content)
4714
            );
4715
4716
        $repositoryMock->expects($this->once())
4717
            ->method('canUser')
4718
            ->with(
4719
                $this->equalTo('content'),
4720
                $this->equalTo('edit'),
4721
                $this->equalTo($content)
4722
            )->will($this->returnValue(true));
4723
4724
        $contentTypeServiceMock->expects($this->once())
4725
            ->method('loadContentType')
4726
            ->with($this->equalTo(24))
4727
            ->will($this->returnValue($contentType));
4728
4729
        $repositoryMock->expects($this->once())
4730
            ->method('getContentTypeService')
4731
            ->will($this->returnValue($contentTypeServiceMock));
4732
4733
        $contentUpdateStruct = new ContentUpdateStruct(
4734
            [
4735
                'fields' => $structFields,
4736
                'initialLanguageCode' => $initialLanguageCode,
4737
            ]
4738
        );
4739
4740
        $mockedService->updateContent($content->versionInfo, $contentUpdateStruct);
4741
    }
4742
4743 View Code Duplication
    public function providerForTestUpdateContentThrowsContentValidationExceptionFieldDefinition()
4744
    {
4745
        return [
4746
            [
4747
                'eng-GB',
4748
                [
4749
                    new Field(
4750
                        [
4751
                            'fieldDefIdentifier' => 'identifier',
4752
                            'value' => 'newValue',
4753
                            'languageCode' => 'eng-GB',
4754
                        ]
4755
                    ),
4756
                ],
4757
            ],
4758
        ];
4759
    }
4760
4761
    /**
4762
     * Test for the updateContent() method.
4763
     *
4764
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4765
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4766
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4767
     * @dataProvider providerForTestUpdateContentThrowsContentValidationExceptionFieldDefinition
4768
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentValidationException
4769
     * @expectedExceptionMessage Field definition 'identifier' does not exist in given ContentType
4770
     */
4771
    public function testUpdateContentThrowsContentValidationExceptionFieldDefinition($initialLanguageCode, $structFields)
4772
    {
4773
        $this->assertForUpdateContentContentValidationException(
4774
            $initialLanguageCode,
4775
            $structFields,
4776
            []
4777
        );
4778
    }
4779
4780 View Code Duplication
    public function providerForTestUpdateContentThrowsContentValidationExceptionTranslation()
4781
    {
4782
        return [
4783
            [
4784
                'eng-US',
4785
                [
4786
                    new Field(
4787
                        [
4788
                            'fieldDefIdentifier' => 'identifier',
4789
                            'value' => 'newValue',
4790
                            'languageCode' => 'eng-US',
4791
                        ]
4792
                    ),
4793
                ],
4794
            ],
4795
        ];
4796
    }
4797
4798
    /**
4799
     * Test for the updateContent() method.
4800
     *
4801
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4802
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4803
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4804
     * @dataProvider providerForTestUpdateContentThrowsContentValidationExceptionTranslation
4805
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentValidationException
4806
     * @expectedExceptionMessage A value is set for non translatable field definition 'identifier' with language 'eng-US'
4807
     */
4808 View Code Duplication
    public function testUpdateContentThrowsContentValidationExceptionTranslation($initialLanguageCode, $structFields)
4809
    {
4810
        $fieldDefinitions = [
4811
            new FieldDefinition(
4812
                [
4813
                    'id' => 'fieldDefinitionId1',
4814
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4815
                    'isTranslatable' => false,
4816
                    'identifier' => 'identifier',
4817
                    'isRequired' => false,
4818
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4819
                ]
4820
            ),
4821
        ];
4822
4823
        $this->assertForUpdateContentContentValidationException(
4824
            $initialLanguageCode,
4825
            $structFields,
4826
            $fieldDefinitions
4827
        );
4828
    }
4829
4830
    public function assertForTestUpdateContentRequiredField(
4831
        $initialLanguageCode,
4832
        $structFields,
4833
        $existingFields,
4834
        $fieldDefinitions
4835
    ) {
4836
        $repositoryMock = $this->getRepositoryMock();
4837
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
4838
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
4839
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
4840
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
4841
        $fieldTypeServiceMock = $this->getFieldTypeServiceMock();
0 ignored issues
show
Unused Code introduced by
$fieldTypeServiceMock 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...
4842
        $fieldTypeMock = $this->getMock('eZ\\Publish\\SPI\\FieldType\\FieldType');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
4843
        $existingLanguageCodes = array_map(
4844
            function (Field $field) {
4845
                return $field->languageCode;
4846
            },
4847
            $existingFields
4848
        );
4849
        $versionInfo = new VersionInfo(
4850
            [
4851
                'contentInfo' => new ContentInfo(
4852
                    [
4853
                        'id' => 42,
4854
                        'contentTypeId' => 24,
4855
                        'mainLanguageCode' => 'eng-GB',
4856
                    ]
4857
                ),
4858
                'versionNo' => 7,
4859
                'languageCodes' => $existingLanguageCodes,
4860
                'status' => VersionInfo::STATUS_DRAFT,
4861
            ]
4862
        );
4863
        $content = new Content(
4864
            [
4865
                'versionInfo' => $versionInfo,
4866
                'internalFields' => $existingFields,
4867
            ]
4868
        );
4869
        $contentType = new ContentType(['fieldDefinitions' => $fieldDefinitions]);
4870
4871
        $languageHandlerMock->expects($this->any())
4872
            ->method('loadByLanguageCode')
4873
            ->with($this->isType('string'))
4874
            ->will(
4875
                $this->returnCallback(
4876
                    function () {
4877
                        return new Language(['id' => 4242]);
4878
                    }
4879
                )
4880
            );
4881
4882
        $mockedService->expects($this->once())
4883
            ->method('loadContent')
4884
            ->with(
4885
                $this->equalTo(42),
4886
                $this->equalTo(null),
4887
                $this->equalTo(7)
4888
            )->will(
4889
                $this->returnValue($content)
4890
            );
4891
4892
        $repositoryMock->expects($this->once())
4893
            ->method('canUser')
4894
            ->with(
4895
                $this->equalTo('content'),
4896
                $this->equalTo('edit'),
4897
                $this->equalTo($content)
4898
            )->will($this->returnValue(true));
4899
4900
        $contentTypeServiceMock->expects($this->once())
4901
            ->method('loadContentType')
4902
            ->with($this->equalTo(24))
4903
            ->will($this->returnValue($contentType));
4904
4905
        $repositoryMock->expects($this->once())
4906
            ->method('getContentTypeService')
4907
            ->will($this->returnValue($contentTypeServiceMock));
4908
4909
        $fieldTypeMock->expects($this->any())
4910
            ->method('acceptValue')
4911
            ->will(
4912
                $this->returnCallback(
4913
                    function ($valueString) {
4914
                        return new ValueStub($valueString);
4915
                    }
4916
                )
4917
            );
4918
4919
        $emptyValue = self::EMPTY_FIELD_VALUE;
4920
        $fieldTypeMock->expects($this->any())
4921
            ->method('isEmptyValue')
4922
            ->will(
4923
                $this->returnCallback(
4924
                    function (ValueStub $value) use ($emptyValue) {
4925
                        return $emptyValue === (string)$value;
4926
                    }
4927
                )
4928
            );
4929
4930
        $fieldTypeMock->expects($this->any())
4931
            ->method('validate')
4932
            ->with(
4933
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\ContentType\\FieldDefinition'),
4934
                $this->isInstanceOf('eZ\\Publish\\Core\\FieldType\\Value')
4935
            );
4936
4937
        $this->getFieldTypeRegistryMock()->expects($this->any())
4938
            ->method('getFieldType')
4939
            ->will($this->returnValue($fieldTypeMock));
4940
4941
        $contentUpdateStruct = new ContentUpdateStruct(
4942
            [
4943
                'fields' => $structFields,
4944
                'initialLanguageCode' => $initialLanguageCode,
4945
            ]
4946
        );
4947
4948
        return [$content->versionInfo, $contentUpdateStruct];
4949
    }
4950
4951 View Code Duplication
    public function providerForTestUpdateContentRequiredField()
4952
    {
4953
        return [
4954
            [
4955
                'eng-US',
4956
                [
4957
                    new Field(
4958
                        [
4959
                            'fieldDefIdentifier' => 'identifier',
4960
                            'value' => self::EMPTY_FIELD_VALUE,
4961
                            'languageCode' => null,
4962
                        ]
4963
                    ),
4964
                ],
4965
                'identifier',
4966
                'eng-US',
4967
            ],
4968
        ];
4969
    }
4970
4971
    /**
4972
     * Test for the updateContent() method.
4973
     *
4974
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4975
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4976
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4977
     * @dataProvider providerForTestUpdateContentRequiredField
4978
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
4979
     */
4980
    public function testUpdateContentRequiredField(
4981
        $initialLanguageCode,
4982
        $structFields,
4983
        $identifier,
4984
        $languageCode
4985
    ) {
4986
        $existingFields = [
4987
            new Field(
4988
                [
4989
                    'id' => '100',
4990
                    'fieldDefIdentifier' => 'identifier',
4991
                    'value' => 'initialValue',
4992
                    'languageCode' => 'eng-GB',
4993
                ]
4994
            ),
4995
        ];
4996
        $fieldDefinitions = [
4997
            new FieldDefinition(
4998
                [
4999
                    'id' => 'fieldDefinitionId',
5000
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
5001
                    'isTranslatable' => true,
5002
                    'identifier' => 'identifier',
5003
                    'isRequired' => true,
5004
                    'defaultValue' => 'defaultValue',
5005
                ]
5006
            ),
5007
        ];
5008
        list($versionInfo, $contentUpdateStruct) =
5009
            $this->assertForTestUpdateContentRequiredField(
5010
                $initialLanguageCode,
5011
                $structFields,
5012
                $existingFields,
5013
                $fieldDefinitions
5014
            );
5015
5016
        try {
5017
            $this->partlyMockedContentService->updateContent($versionInfo, $contentUpdateStruct);
5018
        } catch (ContentValidationException $e) {
5019
            $this->assertEquals(
5020
                "Value for required field definition '{$identifier}' with language '{$languageCode}' is empty",
5021
                $e->getMessage()
5022
            );
5023
5024
            throw $e;
5025
        }
5026
    }
5027
5028
    public function assertForTestUpdateContentThrowsContentFieldValidationException(
5029
        $initialLanguageCode,
5030
        $structFields,
5031
        $existingFields,
5032
        $fieldDefinitions
5033
    ) {
5034
        $repositoryMock = $this->getRepositoryMock();
5035
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
5036
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
5037
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
5038
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
5039
        $fieldTypeMock = $this->getMock('eZ\\Publish\\SPI\\FieldType\\FieldType');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5040
        $existingLanguageCodes = array_map(
5041
            function (Field $field) {
5042
                return $field->languageCode;
5043
            },
5044
            $existingFields
5045
        );
5046
        $languageCodes = $this->determineLanguageCodesForUpdate(
5047
            $initialLanguageCode,
5048
            $structFields,
5049
            $existingLanguageCodes
5050
        );
5051
        $versionInfo = new VersionInfo(
5052
            [
5053
                'contentInfo' => new ContentInfo(
5054
                    [
5055
                        'id' => 42,
5056
                        'contentTypeId' => 24,
5057
                        'mainLanguageCode' => 'eng-GB',
5058
                    ]
5059
                ),
5060
                'versionNo' => 7,
5061
                'languageCodes' => $existingLanguageCodes,
5062
                'status' => VersionInfo::STATUS_DRAFT,
5063
            ]
5064
        );
5065
        $content = new Content(
5066
            [
5067
                'versionInfo' => $versionInfo,
5068
                'internalFields' => $existingFields,
5069
            ]
5070
        );
5071
        $contentType = new ContentType(['fieldDefinitions' => $fieldDefinitions]);
5072
5073
        $languageHandlerMock->expects($this->any())
5074
            ->method('loadByLanguageCode')
5075
            ->with($this->isType('string'))
5076
            ->will(
5077
                $this->returnCallback(
5078
                    function () {
5079
                        return new Language(['id' => 4242]);
5080
                    }
5081
                )
5082
            );
5083
5084
        $mockedService->expects($this->once())
5085
            ->method('loadContent')
5086
            ->with(
5087
                $this->equalTo(42),
5088
                $this->equalTo(null),
5089
                $this->equalTo(7)
5090
            )->will(
5091
                $this->returnValue($content)
5092
            );
5093
5094
        $repositoryMock->expects($this->once())
5095
            ->method('canUser')
5096
            ->with(
5097
                $this->equalTo('content'),
5098
                $this->equalTo('edit'),
5099
                $this->equalTo($content)
5100
            )->will($this->returnValue(true));
5101
5102
        $contentTypeServiceMock->expects($this->once())
5103
            ->method('loadContentType')
5104
            ->with($this->equalTo(24))
5105
            ->will($this->returnValue($contentType));
5106
5107
        $repositoryMock->expects($this->once())
5108
            ->method('getContentTypeService')
5109
            ->will($this->returnValue($contentTypeServiceMock));
5110
5111
        $fieldValues = $this->determineValuesForUpdate(
5112
            $initialLanguageCode,
5113
            $structFields,
5114
            $content,
5115
            $fieldDefinitions,
5116
            $languageCodes
5117
        );
5118
        $allFieldErrors = [];
5119
        $emptyValue = self::EMPTY_FIELD_VALUE;
5120
5121
        $fieldTypeMock->expects($this->exactly(count($fieldValues) * count($languageCodes)))
5122
            ->method('acceptValue')
5123
            ->will(
5124
                $this->returnCallback(
5125
                    function ($valueString) {
5126
                        return new ValueStub($valueString);
5127
                    }
5128
                )
5129
            );
5130
5131
        $fieldTypeMock->expects($this->exactly(count($fieldValues) * count($languageCodes)))
5132
            ->method('isEmptyValue')
5133
            ->will(
5134
                $this->returnCallback(
5135
                    function (ValueStub $value) use ($emptyValue) {
5136
                        return $emptyValue === (string)$value;
5137
                    }
5138
                )
5139
            );
5140
5141
        $fieldTypeMock
5142
            ->expects($this->any())
5143
            ->method('validate')
5144
            ->willReturnArgument(1);
5145
5146
        $this->getFieldTypeRegistryMock()->expects($this->any())
5147
            ->method('getFieldType')
5148
            ->will($this->returnValue($fieldTypeMock));
5149
5150
        $contentUpdateStruct = new ContentUpdateStruct(
5151
            [
5152
                'fields' => $structFields,
5153
                'initialLanguageCode' => $initialLanguageCode,
5154
            ]
5155
        );
5156
5157
        return [$content->versionInfo, $contentUpdateStruct, $allFieldErrors];
5158
    }
5159
5160
    public function providerForTestUpdateContentThrowsContentFieldValidationException()
5161
    {
5162
        $allFieldErrors = [
5163
            [
5164
                'fieldDefinitionId1' => [
5165
                    'eng-GB' => 'newValue1-eng-GB',
5166
                    'eng-US' => 'newValue1-eng-GB',
5167
                ],
5168
                'fieldDefinitionId2' => [
5169
                    'eng-GB' => 'initialValue2',
5170
                ],
5171
                'fieldDefinitionId3' => [
5172
                    'eng-GB' => 'initialValue3',
5173
                    'eng-US' => 'initialValue3',
5174
                ],
5175
                'fieldDefinitionId4' => [
5176
                    'eng-GB' => 'initialValue4',
5177
                    'eng-US' => 'newValue4',
5178
                ],
5179
            ],
5180
            [
5181
                'fieldDefinitionId1' => [
5182
                    'eng-GB' => 'newValue1-eng-GB',
5183
                    'eng-US' => 'newValue1-eng-GB',
5184
                ],
5185
                'fieldDefinitionId2' => [
5186
                    'eng-GB' => 'initialValue2',
5187
                ],
5188
                'fieldDefinitionId3' => [
5189
                    'eng-GB' => 'initialValue3',
5190
                    'eng-US' => 'initialValue3',
5191
                ],
5192
                'fieldDefinitionId4' => [
5193
                    'eng-GB' => 'initialValue4',
5194
                    'eng-US' => 'newValue4',
5195
                ],
5196
            ],
5197
            [
5198
                'fieldDefinitionId1' => [
5199
                    'eng-GB' => 'newValue1-eng-GB',
5200
                    'eng-US' => 'newValue1-eng-GB',
5201
                ],
5202
                'fieldDefinitionId2' => [
5203
                    'eng-GB' => 'initialValue2',
5204
                    'eng-US' => 'newValue2',
5205
                ],
5206
                'fieldDefinitionId3' => [
5207
                    'eng-GB' => 'initialValue3',
5208
                    'eng-US' => 'initialValue3',
5209
                ],
5210
                'fieldDefinitionId4' => [
5211
                    'eng-GB' => 'initialValue4',
5212
                    'eng-US' => 'defaultValue4',
5213
                ],
5214
            ],
5215
            [
5216
                'fieldDefinitionId1' => [
5217
                    'eng-GB' => 'newValue1-eng-GB',
5218
                    'eng-US' => 'newValue1-eng-GB',
5219
                ],
5220
                'fieldDefinitionId2' => [
5221
                    'eng-GB' => 'initialValue2',
5222
                    'eng-US' => 'newValue2',
5223
                ],
5224
                'fieldDefinitionId3' => [
5225
                    'eng-GB' => 'initialValue3',
5226
                    'eng-US' => 'initialValue3',
5227
                ],
5228
                'fieldDefinitionId4' => [
5229
                    'eng-GB' => 'initialValue4',
5230
                    'eng-US' => 'defaultValue4',
5231
                ],
5232
            ],
5233
            [
5234
                'fieldDefinitionId1' => [
5235
                    'eng-GB' => 'newValue1-eng-GB',
5236
                    'ger-DE' => 'newValue1-eng-GB',
5237
                    'eng-US' => 'newValue1-eng-GB',
5238
                ],
5239
                'fieldDefinitionId2' => [
5240
                    'eng-GB' => 'initialValue2',
5241
                    'eng-US' => 'newValue2',
5242
                ],
5243
                'fieldDefinitionId3' => [
5244
                    'eng-GB' => 'initialValue3',
5245
                    'ger-DE' => 'initialValue3',
5246
                    'eng-US' => 'initialValue3',
5247
                ],
5248
                'fieldDefinitionId4' => [
5249
                    'eng-GB' => 'initialValue4',
5250
                    'eng-US' => 'defaultValue4',
5251
                    'ger-DE' => 'defaultValue4',
5252
                ],
5253
            ],
5254
            [
5255
                'fieldDefinitionId1' => [
5256
                    'eng-US' => 'newValue1-eng-GB',
5257
                    'ger-DE' => 'newValue1-eng-GB',
5258
                ],
5259
                'fieldDefinitionId2' => [
5260
                    'eng-US' => 'newValue2',
5261
                ],
5262
                'fieldDefinitionId3' => [
5263
                    'ger-DE' => 'initialValue3',
5264
                    'eng-US' => 'initialValue3',
5265
                ],
5266
                'fieldDefinitionId4' => [
5267
                    'ger-DE' => 'defaultValue4',
5268
                    'eng-US' => 'defaultValue4',
5269
                ],
5270
            ],
5271
        ];
5272
5273
        $data = $this->providerForTestUpdateContentNonRedundantFieldSetComplex();
5274
        $count = count($data);
5275
        for ($i = 0; $i < $count; ++$i) {
5276
            $data[$i][] = $allFieldErrors[$i];
5277
        }
5278
5279
        return $data;
5280
    }
5281
5282
    /**
5283
     * Test for the updateContent() method.
5284
     *
5285
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
5286
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
5287
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
5288
     * @dataProvider providerForTestUpdateContentThrowsContentFieldValidationException
5289
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
5290
     * @expectedExceptionMessage Content fields did not validate
5291
     */
5292
    public function testUpdateContentThrowsContentFieldValidationException($initialLanguageCode, $structFields, $spiField, $allFieldErrors)
0 ignored issues
show
Unused Code introduced by
The parameter $spiField 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...
5293
    {
5294
        list($existingFields, $fieldDefinitions) = $this->fixturesForTestUpdateContentNonRedundantFieldSetComplex();
5295
        list($versionInfo, $contentUpdateStruct) =
5296
            $this->assertForTestUpdateContentThrowsContentFieldValidationException(
5297
                $initialLanguageCode,
5298
                $structFields,
5299
                $existingFields,
5300
                $fieldDefinitions
5301
            );
5302
5303
        try {
5304
            $this->partlyMockedContentService->updateContent($versionInfo, $contentUpdateStruct);
5305
        } catch (ContentFieldValidationException $e) {
5306
            $this->assertEquals($allFieldErrors, $e->getFieldErrors());
5307
            throw $e;
5308
        }
5309
    }
5310
5311
    /**
5312
     * Test for the updateContent() method.
5313
     *
5314
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
5315
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
5316
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
5317
     * @expectedException \Exception
5318
     * @expectedExceptionMessage Store failed
5319
     */
5320
    public function testUpdateContentTransactionRollback()
5321
    {
5322
        $existingFields = [
5323
            new Field(
5324
                [
5325
                    'id' => '100',
5326
                    'fieldDefIdentifier' => 'identifier',
5327
                    'value' => 'initialValue',
5328
                    'languageCode' => 'eng-GB',
5329
                ]
5330
            ),
5331
        ];
5332
5333
        $fieldDefinitions = [
5334
            new FieldDefinition(
5335
                [
5336
                    'id' => 'fieldDefinitionId',
5337
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
5338
                    'isTranslatable' => false,
5339
                    'identifier' => 'identifier',
5340
                    'isRequired' => false,
5341
                    'defaultValue' => 'defaultValue',
5342
                ]
5343
            ),
5344
        ];
5345
5346
        // Setup a simple case that will pass
5347
        list($versionInfo, $contentUpdateStruct) = $this->assertForTestUpdateContentNonRedundantFieldSet(
5348
            'eng-US',
5349
            [],
5350
            [],
5351
            $existingFields,
5352
            $fieldDefinitions,
5353
            // Do not execute test
5354
            false
5355
        );
5356
5357
        $repositoryMock = $this->getRepositoryMock();
5358
        $repositoryMock->expects($this->never())->method('commit');
5359
        $repositoryMock->expects($this->once())->method('rollback');
5360
5361
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5362
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5363
        $contentHandlerMock->expects($this->once())
5364
            ->method('updateContent')
5365
            ->with(
5366
                $this->anything(),
5367
                $this->anything(),
5368
                $this->anything()
5369
            )->will($this->throwException(new \Exception('Store failed')));
5370
5371
        // Execute
5372
        $this->partlyMockedContentService->updateContent($versionInfo, $contentUpdateStruct);
5373
    }
5374
5375
    /**
5376
     * Test for the copyContent() method.
5377
     *
5378
     * @covers \eZ\Publish\Core\Repository\ContentService::copyContent
5379
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
5380
     */
5381
    public function testCopyContentThrowsUnauthorizedException()
5382
    {
5383
        $repository = $this->getRepositoryMock();
5384
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo']);
5385
        $contentInfo = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5386
        $locationCreateStruct = new LocationCreateStruct();
5387
        $location = new Location(['id' => $locationCreateStruct->parentLocationId]);
5388
        $locationServiceMock = $this->getLocationServiceMock();
5389
5390
        $repository->expects($this->once())
5391
            ->method('getLocationService')
5392
            ->will($this->returnValue($locationServiceMock))
5393
        ;
5394
5395
        $locationServiceMock->expects($this->once())
5396
            ->method('loadLocation')
5397
            ->with(
5398
                $locationCreateStruct->parentLocationId
5399
            )
5400
            ->will($this->returnValue($location))
5401
        ;
5402
5403
        $contentInfo->expects($this->any())
5404
            ->method('__get')
5405
            ->with('sectionId')
5406
            ->will($this->returnValue(42));
5407
5408
        $repository->expects($this->once())
5409
            ->method('canUser')
5410
            ->with(
5411
                'content',
5412
                'create',
5413
                $contentInfo,
5414
                [$location]
5415
            )
5416
            ->will($this->returnValue(false));
5417
5418
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */
5419
        $contentService->copyContent($contentInfo, $locationCreateStruct);
5420
    }
5421
5422
    /**
5423
     * Test for the copyContent() method.
5424
     *
5425
     * @covers \eZ\Publish\Core\Repository\ContentService::copyContent
5426
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
5427
     * @covers \eZ\Publish\Core\Repository\ContentService::internalPublishVersion
5428
     */
5429
    public function testCopyContent()
5430
    {
5431
        $repositoryMock = $this->getRepositoryMock();
5432
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo', 'internalLoadContent']);
5433
        $locationServiceMock = $this->getLocationServiceMock();
5434
        $contentInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5435
        $locationCreateStruct = new LocationCreateStruct();
5436
        $location = new Location(['id' => $locationCreateStruct->parentLocationId]);
5437
        $user = $this->getStubbedUser(14);
5438
5439
        $permissionResolverMock = $this
5440
            ->getMockBuilder('eZ\\Publish\\API\\Repository\\PermissionResolver')
5441
            ->disableOriginalConstructor()
5442
            ->getMock();
5443
5444
        $permissionResolverMock
5445
            ->method('getCurrentUserReference')
5446
            ->willReturn($user);
5447
5448
        $repositoryMock
5449
            ->method('getPermissionResolver')
5450
            ->willReturn($permissionResolverMock);
5451
5452
        $repositoryMock->expects($this->exactly(3))
5453
            ->method('getLocationService')
5454
            ->will($this->returnValue($locationServiceMock));
5455
5456
        $locationServiceMock->expects($this->once())
5457
            ->method('loadLocation')
5458
            ->with($locationCreateStruct->parentLocationId)
5459
            ->will($this->returnValue($location))
5460
        ;
5461
5462
        $contentInfoMock->expects($this->any())
5463
            ->method('__get')
5464
            ->with('id')
5465
            ->will($this->returnValue(42));
5466
        $versionInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5467
5468
        $versionInfoMock->expects($this->any())
5469
            ->method('__get')
5470
            ->will(
5471
                $this->returnValueMap(
5472
                    [
5473
                        ['versionNo', 123],
5474
                        ['status', VersionInfo::STATUS_DRAFT],
5475
                    ]
5476
                )
5477
            );
5478
        $versionInfoMock->expects($this->once())
5479
            ->method('getContentInfo')
5480
            ->will($this->returnValue($contentInfoMock));
5481
5482
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5483
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5484
        $domainMapperMock = $this->getDomainMapperMock();
5485
5486
        $repositoryMock->expects($this->once())->method('beginTransaction');
5487
        $repositoryMock->expects($this->once())->method('commit');
5488
        $repositoryMock->expects($this->once())
5489
            ->method('canUser')
5490
            ->with(
5491
                'content',
5492
                'create',
5493
                $contentInfoMock,
5494
                [$location]
5495
            )
5496
            ->will($this->returnValue(true));
5497
5498
        $spiContentInfo = new SPIContentInfo(['id' => 42]);
5499
        $spiVersionInfo = new SPIVersionInfo(
5500
            [
5501
                'contentInfo' => $spiContentInfo,
5502
                'creationDate' => 123456,
5503
            ]
5504
        );
5505
        $spiContent = new SPIContent(['versionInfo' => $spiVersionInfo]);
5506
        $contentHandlerMock->expects($this->once())
5507
            ->method('copy')
5508
            ->with(42, null)
5509
            ->will($this->returnValue($spiContent));
5510
5511
        $this->mockGetDefaultObjectStates();
5512
        $this->mockSetDefaultObjectStates();
5513
5514
        $domainMapperMock->expects($this->once())
5515
            ->method('buildVersionInfoDomainObject')
5516
            ->with($spiVersionInfo)
5517
            ->will($this->returnValue($versionInfoMock));
5518
5519
        /* @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfoMock */
5520
        $content = $this->mockPublishVersion(123456);
5521
        $locationServiceMock->expects($this->once())
5522
            ->method('createLocation')
5523
            ->with(
5524
                $content->getVersionInfo()->getContentInfo(),
5525
                $locationCreateStruct
5526
            );
5527
5528
        $contentService->expects($this->once())
5529
            ->method('internalLoadContent')
5530
            ->with(
5531
                $content->id
5532
            )
5533
            ->will($this->returnValue($content));
5534
5535
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfoMock */
5536
        $contentService->copyContent($contentInfoMock, $locationCreateStruct, null);
5537
    }
5538
5539
    /**
5540
     * Test for the copyContent() method.
5541
     *
5542
     * @covers \eZ\Publish\Core\Repository\ContentService::copyContent
5543
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
5544
     * @covers \eZ\Publish\Core\Repository\ContentService::internalPublishVersion
5545
     */
5546
    public function testCopyContentWithVersionInfo()
5547
    {
5548
        $repositoryMock = $this->getRepositoryMock();
5549
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo', 'internalLoadContent']);
5550
        $locationServiceMock = $this->getLocationServiceMock();
5551
        $contentInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5552
        $locationCreateStruct = new LocationCreateStruct();
5553
        $location = new Location(['id' => $locationCreateStruct->parentLocationId]);
5554
        $user = $this->getStubbedUser(14);
5555
5556
        $permissionResolverMock = $this
5557
            ->getMockBuilder('eZ\\Publish\\API\\Repository\\PermissionResolver')
5558
            ->disableOriginalConstructor()
5559
            ->getMock();
5560
5561
        $permissionResolverMock
5562
            ->method('getCurrentUserReference')
5563
            ->willReturn($user);
5564
5565
        $repositoryMock
5566
            ->method('getPermissionResolver')
5567
            ->willReturn($permissionResolverMock);
5568
5569
        $repositoryMock->expects($this->exactly(3))
5570
            ->method('getLocationService')
5571
            ->will($this->returnValue($locationServiceMock));
5572
5573
        $locationServiceMock->expects($this->once())
5574
            ->method('loadLocation')
5575
            ->with($locationCreateStruct->parentLocationId)
5576
            ->will($this->returnValue($location))
5577
        ;
5578
5579
        $contentInfoMock->expects($this->any())
5580
            ->method('__get')
5581
            ->with('id')
5582
            ->will($this->returnValue(42));
5583
        $versionInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5584
5585
        $versionInfoMock->expects($this->any())
5586
            ->method('__get')
5587
            ->will(
5588
                $this->returnValueMap(
5589
                    [
5590
                        ['versionNo', 123],
5591
                        ['status', VersionInfo::STATUS_DRAFT],
5592
                    ]
5593
                )
5594
            );
5595
        $versionInfoMock->expects($this->once())
5596
            ->method('getContentInfo')
5597
            ->will($this->returnValue($contentInfoMock));
5598
5599
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5600
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5601
        $domainMapperMock = $this->getDomainMapperMock();
5602
5603
        $repositoryMock->expects($this->once())->method('beginTransaction');
5604
        $repositoryMock->expects($this->once())->method('commit');
5605
        $repositoryMock->expects($this->once())
5606
            ->method('canUser')
5607
            ->with(
5608
                'content',
5609
                'create',
5610
                $contentInfoMock,
5611
                [$location]
5612
            )
5613
            ->will($this->returnValue(true));
5614
5615
        $spiContentInfo = new SPIContentInfo(['id' => 42]);
5616
        $spiVersionInfo = new SPIVersionInfo(
5617
            [
5618
                'contentInfo' => $spiContentInfo,
5619
                'creationDate' => 123456,
5620
            ]
5621
        );
5622
        $spiContent = new SPIContent(['versionInfo' => $spiVersionInfo]);
5623
        $contentHandlerMock->expects($this->once())
5624
            ->method('copy')
5625
            ->with(42, 123)
5626
            ->will($this->returnValue($spiContent));
5627
5628
        $this->mockGetDefaultObjectStates();
5629
        $this->mockSetDefaultObjectStates();
5630
5631
        $domainMapperMock->expects($this->once())
5632
            ->method('buildVersionInfoDomainObject')
5633
            ->with($spiVersionInfo)
5634
            ->will($this->returnValue($versionInfoMock));
5635
5636
        /* @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfoMock */
5637
        $content = $this->mockPublishVersion(123456);
5638
        $locationServiceMock->expects($this->once())
5639
            ->method('createLocation')
5640
            ->with(
5641
                $content->getVersionInfo()->getContentInfo(),
5642
                $locationCreateStruct
5643
            );
5644
5645
        $contentService->expects($this->once())
5646
            ->method('internalLoadContent')
5647
            ->with(
5648
                $content->id
5649
            )
5650
            ->will($this->returnValue($content));
5651
5652
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfoMock */
5653
        $contentService->copyContent($contentInfoMock, $locationCreateStruct, $versionInfoMock);
5654
    }
5655
5656
    /**
5657
     * Test for the copyContent() method.
5658
     *
5659
     * @covers \eZ\Publish\Core\Repository\ContentService::copyContent
5660
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
5661
     * @covers \eZ\Publish\Core\Repository\ContentService::internalPublishVersion
5662
     * @expectedException \Exception
5663
     * @expectedExceptionMessage Handler threw an exception
5664
     */
5665
    public function testCopyContentWithRollback()
5666
    {
5667
        $repositoryMock = $this->getRepositoryMock();
5668
        $contentService = $this->getPartlyMockedContentService();
5669
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5670
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5671
        $locationCreateStruct = new LocationCreateStruct();
5672
        $location = new Location(['id' => $locationCreateStruct->parentLocationId]);
5673
        $locationServiceMock = $this->getLocationServiceMock();
5674
        $user = $this->getStubbedUser(14);
5675
5676
        $permissionResolverMock = $this
5677
            ->getMockBuilder('eZ\\Publish\\API\\Repository\\PermissionResolver')
5678
            ->disableOriginalConstructor()
5679
            ->getMock();
5680
5681
        $permissionResolverMock
5682
            ->method('getCurrentUserReference')
5683
            ->willReturn($user);
5684
5685
        $repositoryMock
5686
            ->method('getPermissionResolver')
5687
            ->willReturn($permissionResolverMock);
5688
5689
        $repositoryMock->expects($this->once())
5690
            ->method('getLocationService')
5691
            ->will($this->returnValue($locationServiceMock))
5692
        ;
5693
5694
        $locationServiceMock->expects($this->once())
5695
            ->method('loadLocation')
5696
            ->with($locationCreateStruct->parentLocationId)
5697
            ->will($this->returnValue($location))
5698
        ;
5699
5700
        $contentInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5701
        $contentInfoMock->expects($this->any())
5702
            ->method('__get')
5703
            ->with('id')
5704
            ->will($this->returnValue(42));
5705
5706
        $this->mockGetDefaultObjectStates();
5707
5708
        $repositoryMock->expects($this->once())->method('beginTransaction');
5709
        $repositoryMock->expects($this->once())->method('rollback');
5710
        $repositoryMock->expects($this->once())
5711
            ->method('canUser')
5712
            ->with(
5713
                'content',
5714
                'create',
5715
                $contentInfoMock,
5716
                [$location]
5717
            )
5718
            ->will($this->returnValue(true));
5719
5720
        $contentHandlerMock->expects($this->once())
5721
            ->method('copy')
5722
            ->with(42, null)
5723
            ->will($this->throwException(new Exception('Handler threw an exception')));
5724
5725
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfoMock */
5726
        $contentService->copyContent($contentInfoMock, $locationCreateStruct, null);
5727
    }
5728
5729
    protected function mockGetDefaultObjectStates()
5730
    {
5731
        /** @var \PHPUnit_Framework_MockObject_MockObject $objectStateHandlerMock */
5732
        $objectStateHandlerMock = $this->getPersistenceMock()->objectStateHandler();
5733
5734
        $objectStateGroups = [
5735
            new SPIObjectStateGroup(['id' => 10]),
5736
            new SPIObjectStateGroup(['id' => 20]),
5737
        ];
5738
5739
        /* @var \PHPUnit_Framework_MockObject_MockObject $objectStateHandlerMock */
5740
        $objectStateHandlerMock->expects($this->once())
5741
            ->method('loadAllGroups')
5742
            ->will($this->returnValue($objectStateGroups));
5743
5744
        $objectStateHandlerMock->expects($this->at(1))
5745
            ->method('loadObjectStates')
5746
            ->with($this->equalTo(10))
5747
            ->will(
5748
                $this->returnValue(
5749
                    [
5750
                        new SPIObjectState(['id' => 11, 'groupId' => 10]),
5751
                        new SPIObjectState(['id' => 12, 'groupId' => 10]),
5752
                    ]
5753
                )
5754
            );
5755
5756
        $objectStateHandlerMock->expects($this->at(2))
5757
            ->method('loadObjectStates')
5758
            ->with($this->equalTo(20))
5759
            ->will(
5760
                $this->returnValue(
5761
                    [
5762
                        new SPIObjectState(['id' => 21, 'groupId' => 20]),
5763
                        new SPIObjectState(['id' => 22, 'groupId' => 20]),
5764
                    ]
5765
                )
5766
            );
5767
    }
5768
5769
    protected function mockSetDefaultObjectStates()
5770
    {
5771
        /** @var \PHPUnit_Framework_MockObject_MockObject $objectStateHandlerMock */
5772
        $objectStateHandlerMock = $this->getPersistenceMock()->objectStateHandler();
5773
5774
        $defaultObjectStates = [
5775
            new SPIObjectState(['id' => 11, 'groupId' => 10]),
5776
            new SPIObjectState(['id' => 21, 'groupId' => 20]),
5777
        ];
5778
        foreach ($defaultObjectStates as $index => $objectState) {
5779
            $objectStateHandlerMock->expects($this->at($index + 3))
5780
                ->method('setContentState')
5781
                ->with(
5782
                    42,
5783
                    $objectState->groupId,
5784
                    $objectState->id
5785
                );
5786
        }
5787
    }
5788
5789
    /**
5790
     * @param int|null $publicationDate
5791
     *
5792
     * @return \eZ\Publish\API\Repository\Values\Content\Content
5793
     */
5794
    protected function mockPublishVersion($publicationDate = null)
5795
    {
5796
        $domainMapperMock = $this->getDomainMapperMock();
5797
        $contentMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\Content');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5798
        /* @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5799
        $versionInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5800
        $contentInfoMock = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5801
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5802
        $metadataUpdateStruct = new SPIMetadataUpdateStruct();
5803
5804
        $contentMock->expects($this->any())
5805
            ->method('__get')
5806
            ->will(
5807
                $this->returnValueMap(
5808
                    [
5809
                        ['id', 42],
5810
                        ['contentInfo', $contentInfoMock],
5811
                    ]
5812
                )
5813
            );
5814
        $contentMock->expects($this->any())
5815
            ->method('getVersionInfo')
5816
            ->will($this->returnValue($versionInfoMock));
5817
        $versionInfoMock->expects($this->any())
5818
            ->method('getContentInfo')
5819
            ->will($this->returnValue($contentInfoMock));
5820
        $contentInfoMock->expects($this->any())
5821
            ->method('__get')
5822
            ->will(
5823
                $this->returnValueMap(
5824
                    [
5825
                        ['alwaysAvailable', true],
5826
                        ['mainLanguageCode', 'eng-GB'],
5827
                    ]
5828
                )
5829
            );
5830
5831
        $currentTime = time();
5832
        if ($publicationDate === null && $versionInfoMock->versionNo === 1) {
5833
            $publicationDate = $currentTime;
5834
        }
5835
5836
        // Account for 1 second of test execution time
5837
        $metadataUpdateStruct->publicationDate = $publicationDate;
5838
        $metadataUpdateStruct->modificationDate = $currentTime;
5839
        $metadataUpdateStruct2 = clone $metadataUpdateStruct;
5840
        ++$metadataUpdateStruct2->publicationDate;
5841
        ++$metadataUpdateStruct2->modificationDate;
5842
5843
        $spiContent = new SPIContent();
5844
        $contentHandlerMock->expects($this->once())
5845
            ->method('publish')
5846
            ->with(
5847
                42,
5848
                123,
5849
                $this->logicalOr($metadataUpdateStruct, $metadataUpdateStruct2)
5850
            )
5851
            ->will($this->returnValue($spiContent));
5852
5853
        $domainMapperMock->expects($this->once())
5854
            ->method('buildContentDomainObject')
5855
            ->with($spiContent)
5856
            ->will($this->returnValue($contentMock));
5857
5858
        /* @var \eZ\Publish\API\Repository\Values\Content\Content $contentMock */
5859
        $this->mockPublishUrlAliasesForContent($contentMock);
5860
5861
        return $contentMock;
5862
    }
5863
5864
    /**
5865
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
5866
     */
5867
    protected function mockPublishUrlAliasesForContent(APIContent $content)
5868
    {
5869
        $nameSchemaServiceMock = $this->getNameSchemaServiceMock();
5870
        /** @var \PHPUnit_Framework_MockObject_MockObject $urlAliasHandlerMock */
5871
        $urlAliasHandlerMock = $this->getPersistenceMock()->urlAliasHandler();
5872
        $locationServiceMock = $this->getLocationServiceMock();
5873
        $location = $this->getMock('eZ\\Publish\\API\\Repository\\Values\\Content\\Location');
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
5874
5875
        $location->expects($this->at(0))
5876
            ->method('__get')
5877
            ->with('id')
5878
            ->will($this->returnValue(123));
5879
        $location->expects($this->at(1))
5880
            ->method('__get')
5881
            ->with('parentLocationId')
5882
            ->will($this->returnValue(456));
5883
5884
        $urlAliasNames = ['eng-GB' => 'hello'];
5885
        $nameSchemaServiceMock->expects($this->once())
5886
            ->method('resolveUrlAliasSchema')
5887
            ->with($content)
5888
            ->will($this->returnValue($urlAliasNames));
5889
5890
        $locationServiceMock->expects($this->once())
5891
            ->method('loadLocations')
5892
            ->with($content->getVersionInfo()->getContentInfo())
5893
            ->will($this->returnValue([$location]));
5894
5895
        $urlAliasHandlerMock->expects($this->once())
5896
            ->method('publishUrlAliasForLocation')
5897
            ->with(123, 456, 'hello', 'eng-GB', true, true);
5898
    }
5899
5900
    protected $domainMapperMock;
5901
5902
    /**
5903
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\Core\Repository\Helper\DomainMapper
5904
     */
5905 View Code Duplication
    protected function getDomainMapperMock()
5906
    {
5907
        if (!isset($this->domainMapperMock)) {
5908
            $this->domainMapperMock = $this
5909
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Helper\\DomainMapper')
5910
                ->disableOriginalConstructor()
5911
                ->getMock();
5912
        }
5913
5914
        return $this->domainMapperMock;
5915
    }
5916
5917
    protected $relationProcessorMock;
5918
5919
    /**
5920
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\Core\Repository\Helper\RelationProcessor
5921
     */
5922
    protected function getRelationProcessorMock()
5923
    {
5924
        if (!isset($this->relationProcessorMock)) {
5925
            $this->relationProcessorMock = $this
5926
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Helper\\RelationProcessor')
5927
                ->disableOriginalConstructor()
5928
                ->getMock();
5929
        }
5930
5931
        return $this->relationProcessorMock;
5932
    }
5933
5934
    protected $nameSchemaServiceMock;
5935
5936
    /**
5937
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\Core\Repository\Helper\NameSchemaService
5938
     */
5939
    protected function getNameSchemaServiceMock()
5940
    {
5941
        if (!isset($this->nameSchemaServiceMock)) {
5942
            $this->nameSchemaServiceMock = $this
5943
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Helper\\NameSchemaService')
5944
                ->disableOriginalConstructor()
5945
                ->getMock();
5946
        }
5947
5948
        return $this->nameSchemaServiceMock;
5949
    }
5950
5951
    protected $contentTypeServiceMock;
5952
5953
    /**
5954
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\API\Repository\ContentTypeService
5955
     */
5956
    protected function getContentTypeServiceMock()
5957
    {
5958
        if (!isset($this->contentTypeServiceMock)) {
5959
            $this->contentTypeServiceMock = $this
5960
                ->getMockBuilder('eZ\\Publish\\API\\Repository\\ContentTypeService')
5961
                ->disableOriginalConstructor()
5962
                ->getMock();
5963
        }
5964
5965
        return $this->contentTypeServiceMock;
5966
    }
5967
5968
    protected $locationServiceMock;
5969
5970
    /**
5971
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\API\Repository\LocationService
5972
     */
5973
    protected function getLocationServiceMock()
5974
    {
5975
        if (!isset($this->locationServiceMock)) {
5976
            $this->locationServiceMock = $this
5977
                ->getMockBuilder('eZ\\Publish\\API\\Repository\\LocationService')
5978
                ->disableOriginalConstructor()
5979
                ->getMock();
5980
        }
5981
5982
        return $this->locationServiceMock;
5983
    }
5984
5985
    /**
5986
     * @var \eZ\Publish\Core\Repository\ContentService
5987
     */
5988
    protected $partlyMockedContentService;
5989
5990
    /**
5991
     * Returns the content service to test with $methods mocked.
5992
     *
5993
     * Injected Repository comes from {@see getRepositoryMock()} and persistence handler from {@see getPersistenceMock()}
5994
     *
5995
     * @param string[] $methods
5996
     *
5997
     * @return \eZ\Publish\Core\Repository\ContentService|\PHPUnit_Framework_MockObject_MockObject
5998
     */
5999
    protected function getPartlyMockedContentService(array $methods = null)
6000
    {
6001
        if (!isset($this->partlyMockedContentService)) {
6002
            $this->partlyMockedContentService = $this->getMock(
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() has been deprecated with message: Since PHPUnit 5.4, marked as deprecated here to make it clear when working on 6.7/5.4 branches
{@inheritdoc}

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...
6003
                'eZ\\Publish\\Core\\Repository\\ContentService',
6004
                $methods,
0 ignored issues
show
Bug introduced by
It seems like $methods defined by parameter $methods on line 5999 can also be of type null; however, eZ\Publish\Core\Base\Tes...5CompatTrait::getMock() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
6005
                [
6006
                    $this->getRepositoryMock(),
6007
                    $this->getPersistenceMock(),
6008
                    $this->getDomainMapperMock(),
6009
                    $this->getRelationProcessorMock(),
6010
                    $this->getNameSchemaServiceMock(),
6011
                    $this->getFieldTypeRegistryMock(),
6012
                    [],
6013
                ]
6014
            );
6015
        }
6016
6017
        return $this->partlyMockedContentService;
6018
    }
6019
}
6020