Completed
Push — 6.7_race_cond_testing ( 56a653 )
by André
18:41 queued 11s
created

testLoadVersionInfoByIdAndVersionNumber()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 41
rs 9.264
c 0
b 0
f 0
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
    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->createMock(APIVersionInfo::class);
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
    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->createMock(APIVersionInfo::class);
184
185
        $versionInfoMock->expects($this->any())
186
            ->method('__get')
187
            ->with('status')
188
            ->willReturn(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
            )->willReturn(new SPIVersionInfo());
199
200
        $domainMapperMock->expects($this->once())
201
            ->method('buildVersionInfoDomainObject')
202
            ->with(new SPIVersionInfo())
203
            ->willReturn($versionInfoMock);
204
205
        $repository->expects($this->once())
206
            ->method('canUser')
207
            ->with(
208
                $this->equalTo('content'),
209
                $this->equalTo('versionread'),
210
                $this->equalTo($versionInfoMock)
211
            )->willReturn(true);
212
213
        $result = $contentServiceMock->loadVersionInfoById(42, 2);
214
215
        $this->assertEquals($versionInfoMock, $result);
216
    }
217
218
    /**
219
     * Test for the loadVersionInfo() method.
220
     *
221
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
222
     * @expectedException \eZ\Publish\Core\Base\Exceptions\NotFoundException
223
     */
224
    public function testLoadVersionInfoByIdThrowsNotFoundException()
225
    {
226
        $contentServiceMock = $this->getPartlyMockedContentService(['loadContentInfo']);
227
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
228
        $contentHandler = $this->getPersistenceMock()->contentHandler();
229
230
        $contentHandler->expects($this->once())
231
            ->method('loadVersionInfo')
232
            ->with(
233
                $this->equalTo(42),
234
                $this->equalTo(24)
235
            )->will(
236
                $this->throwException(
237
                    new NotFoundException(
238
                        'Content',
239
                        [
240
                            'contentId' => 42,
241
                            'versionNo' => 24,
242
                        ]
243
                    )
244
                )
245
            );
246
247
        $contentServiceMock->loadVersionInfoById(42, 24);
248
    }
249
250
    /**
251
     * Test for the loadVersionInfo() method.
252
     *
253
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
254
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
255
     */
256
    public function testLoadVersionInfoByIdThrowsUnauthorizedExceptionNonPublishedVersion()
257
    {
258
        $repository = $this->getRepositoryMock();
259
        $contentServiceMock = $this->getPartlyMockedContentService();
260
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
261
        $contentHandler = $this->getPersistenceMock()->contentHandler();
262
        $domainMapperMock = $this->getDomainMapperMock();
263
        $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...
264
265
        $versionInfoMock->expects($this->any())
266
            ->method('__get')
267
            ->with('status')
268
            ->will($this->returnValue(APIVersionInfo::STATUS_DRAFT));
269
270
        $contentHandler->expects($this->once())
271
            ->method('loadVersionInfo')
272
            ->with(
273
                $this->equalTo(42),
274
                $this->equalTo(24)
275
            )->will(
276
                $this->returnValue(new SPIVersionInfo())
277
            );
278
279
        $domainMapperMock->expects($this->once())
280
            ->method('buildVersionInfoDomainObject')
281
            ->with(new SPIVersionInfo())
282
            ->will($this->returnValue($versionInfoMock));
283
284
        $repository->expects($this->once())
285
            ->method('canUser')
286
            ->with(
287
                $this->equalTo('content'),
288
                $this->equalTo('versionread'),
289
                $this->equalTo($versionInfoMock)
290
            )->will($this->returnValue(false));
291
292
        $contentServiceMock->loadVersionInfoById(42, 24);
293
    }
294
295
    /**
296
     * Test for the loadVersionInfo() method.
297
     *
298
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
299
     */
300 View Code Duplication
    public function testLoadVersionInfoByIdPublishedVersion()
301
    {
302
        $repository = $this->getRepositoryMock();
303
        $contentServiceMock = $this->getPartlyMockedContentService();
304
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
305
        $contentHandler = $this->getPersistenceMock()->contentHandler();
306
        $domainMapperMock = $this->getDomainMapperMock();
307
        $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...
308
309
        $versionInfoMock->expects($this->any())
310
            ->method('__get')
311
            ->with('status')
312
            ->will($this->returnValue(APIVersionInfo::STATUS_PUBLISHED));
313
314
        $contentHandler->expects($this->once())
315
            ->method('loadVersionInfo')
316
            ->with(
317
                $this->equalTo(42),
318
                $this->equalTo(24)
319
            )->will(
320
                $this->returnValue(new SPIVersionInfo())
321
            );
322
323
        $domainMapperMock->expects($this->once())
324
            ->method('buildVersionInfoDomainObject')
325
            ->with(new SPIVersionInfo())
326
            ->will($this->returnValue($versionInfoMock));
327
328
        $repository->expects($this->once())
329
            ->method('canUser')
330
            ->with(
331
                $this->equalTo('content'),
332
                $this->equalTo('read'),
333
                $this->equalTo($versionInfoMock)
334
            )->will($this->returnValue(true));
335
336
        $result = $contentServiceMock->loadVersionInfoById(42, 24);
337
338
        $this->assertEquals($versionInfoMock, $result);
339
    }
340
341
    /**
342
     * Test for the loadVersionInfo() method.
343
     *
344
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
345
     */
346 View Code Duplication
    public function testLoadVersionInfoByIdNonPublishedVersion()
347
    {
348
        $repository = $this->getRepositoryMock();
349
        $contentServiceMock = $this->getPartlyMockedContentService();
350
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
351
        $contentHandler = $this->getPersistenceMock()->contentHandler();
352
        $domainMapperMock = $this->getDomainMapperMock();
353
        $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...
354
355
        $versionInfoMock->expects($this->any())
356
            ->method('__get')
357
            ->with('status')
358
            ->will($this->returnValue(APIVersionInfo::STATUS_DRAFT));
359
360
        $contentHandler->expects($this->once())
361
            ->method('loadVersionInfo')
362
            ->with(
363
                $this->equalTo(42),
364
                $this->equalTo(24)
365
            )->will(
366
                $this->returnValue(new SPIVersionInfo())
367
            );
368
369
        $domainMapperMock->expects($this->once())
370
            ->method('buildVersionInfoDomainObject')
371
            ->with(new SPIVersionInfo())
372
            ->will($this->returnValue($versionInfoMock));
373
374
        $repository->expects($this->once())
375
            ->method('canUser')
376
            ->with(
377
                $this->equalTo('content'),
378
                $this->equalTo('versionread'),
379
                $this->equalTo($versionInfoMock)
380
            )->will($this->returnValue(true));
381
382
        $result = $contentServiceMock->loadVersionInfoById(42, 24);
383
384
        $this->assertEquals($versionInfoMock, $result);
385
    }
386
387
    /**
388
     * Test for the loadVersionInfo() method.
389
     *
390
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfo
391
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoById
392
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoByIdThrowsNotFoundException
393
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoByIdThrowsUnauthorizedExceptionNonPublishedVersion
394
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoByIdPublishedVersion
395
     * @depends eZ\Publish\Core\Repository\Tests\Service\Mock\ContentTest::testLoadVersionInfoByIdNonPublishedVersion
396
     */
397
    public function testLoadVersionInfo()
398
    {
399
        $contentServiceMock = $this->getPartlyMockedContentService(
400
            ['loadVersionInfoById']
401
        );
402
        $contentServiceMock->expects(
403
            $this->once()
404
        )->method(
405
            'loadVersionInfoById'
406
        )->with(
407
            $this->equalTo(42),
408
            $this->equalTo(7)
409
        )->will(
410
            $this->returnValue('result')
411
        );
412
413
        $result = $contentServiceMock->loadVersionInfo(
414
            new ContentInfo(['id' => 42]),
415
            7
416
        );
417
418
        $this->assertEquals('result', $result);
419
    }
420
421
    public function testLoadContent()
422
    {
423
        $repository = $this->getRepositoryMock();
424
        $contentService = $this->getPartlyMockedContentService(['internalLoadContent']);
425
        $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...
426
        $versionInfo = $this
427
            ->getMockBuilder('eZ\Publish\API\Repository\Values\Content\VersionInfo')
428
            ->setConstructorArgs([['status' => APIVersionInfo::STATUS_PUBLISHED]])
429
            ->getMockForAbstractClass();
430
        $content
431
            ->expects($this->once())
432
            ->method('getVersionInfo')
433
            ->will($this->returnValue($versionInfo));
434
        $contentId = 123;
435
        $contentService
436
            ->expects($this->once())
437
            ->method('internalLoadContent')
438
            ->with($contentId)
439
            ->will($this->returnValue($content));
440
441
        $repository
442
            ->expects($this->once())
443
            ->method('canUser')
444
            ->with('content', 'read', $content)
445
            ->will($this->returnValue(true));
446
447
        $this->assertSame($content, $contentService->loadContent($contentId));
448
    }
449
450 View Code Duplication
    public function testLoadContentNonPublished()
451
    {
452
        $repository = $this->getRepositoryMock();
453
        $contentService = $this->getPartlyMockedContentService(['internalLoadContent']);
454
        $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...
455
        $versionInfo = $this
456
            ->getMockBuilder('eZ\Publish\API\Repository\Values\Content\VersionInfo')
457
            ->setConstructorArgs([['status' => APIVersionInfo::STATUS_DRAFT]])
458
            ->getMockForAbstractClass();
459
        $content
460
            ->expects($this->once())
461
            ->method('getVersionInfo')
462
            ->will($this->returnValue($versionInfo));
463
        $contentId = 123;
464
        $contentService
465
            ->expects($this->once())
466
            ->method('internalLoadContent')
467
            ->with($contentId)
468
            ->will($this->returnValue($content));
469
470
        $repository
471
            ->expects($this->exactly(2))
472
            ->method('canUser')
473
            ->will(
474
                $this->returnValueMap(
475
                    [
476
                        ['content', 'read', $content, null, true],
477
                        ['content', 'versionread', $content, null, true],
478
                    ]
479
                )
480
            );
481
482
        $this->assertSame($content, $contentService->loadContent($contentId));
483
    }
484
485
    /**
486
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
487
     */
488
    public function testLoadContentUnauthorized()
489
    {
490
        $repository = $this->getRepositoryMock();
491
        $contentService = $this->getPartlyMockedContentService(['internalLoadContent']);
492
        $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...
493
        $contentId = 123;
494
        $contentService
495
            ->expects($this->once())
496
            ->method('internalLoadContent')
497
            ->with($contentId)
498
            ->will($this->returnValue($content));
499
500
        $repository
501
            ->expects($this->once())
502
            ->method('canUser')
503
            ->with('content', 'read', $content)
504
            ->will($this->returnValue(false));
505
506
        $contentService->loadContent($contentId);
507
    }
508
509
    /**
510
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
511
     */
512 View Code Duplication
    public function testLoadContentNotPublishedStatusUnauthorized()
513
    {
514
        $repository = $this->getRepositoryMock();
515
        $contentService = $this->getPartlyMockedContentService(['internalLoadContent']);
516
        $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...
517
        $versionInfo = $this
518
            ->getMockBuilder('eZ\Publish\API\Repository\Values\Content\VersionInfo')
519
            ->setConstructorArgs([['status' => APIVersionInfo::STATUS_DRAFT]])
520
            ->getMockForAbstractClass();
521
        $content
522
            ->expects($this->once())
523
            ->method('getVersionInfo')
524
            ->will($this->returnValue($versionInfo));
525
        $contentId = 123;
526
        $contentService
527
            ->expects($this->once())
528
            ->method('internalLoadContent')
529
            ->with($contentId)
530
            ->will($this->returnValue($content));
531
532
        $repository
533
            ->expects($this->exactly(2))
534
            ->method('canUser')
535
            ->will(
536
                $this->returnValueMap(
537
                    [
538
                        ['content', 'read', $content, null, true],
539
                        ['content', 'versionread', $content, null, false],
540
                    ]
541
                )
542
            );
543
544
        $contentService->loadContent($contentId);
545
    }
546
547
    /**
548
     * @dataProvider internalLoadContentProvider
549
     */
550
    public function testInternalLoadContent($id, $languages, $versionNo, $isRemoteId, $useAlwaysAvailable)
551
    {
552
        $contentService = $this->getPartlyMockedContentService();
553
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
554
        $contentHandler = $this->getPersistenceMock()->contentHandler();
555
        $realId = $id;
556
557
        if ($isRemoteId) {
558
            $realId = 123;
559
            $spiContentInfo = new SPIContentInfo(['currentVersionNo' => $versionNo ?: 7, 'id' => $realId]);
560
            $contentHandler
561
                ->expects($this->once())
562
                ->method('loadContentInfoByRemoteId')
563
                ->with($id)
564
                ->will($this->returnValue($spiContentInfo));
565
        } elseif (!empty($languages) && $useAlwaysAvailable) {
566
            $spiContentInfo = new SPIContentInfo(['alwaysAvailable' => false]);
567
            $contentHandler
568
                ->expects($this->once())
569
                ->method('loadContentInfo')
570
                ->with($id)
571
                ->will($this->returnValue($spiContentInfo));
572
        }
573
574
        $spiContent = new SPIContent();
575
        $contentHandler
576
            ->expects($this->once())
577
            ->method('load')
578
            ->with($realId, $versionNo, $languages)
579
            ->will($this->returnValue($spiContent));
580
        $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...
581
        $this->getDomainMapperMock()
582
            ->expects($this->once())
583
            ->method('buildContentDomainObject')
584
            ->with($spiContent)
585
            ->will($this->returnValue($content));
586
587
        $this->assertSame(
588
            $content,
589
            $contentService->internalLoadContent($id, $languages, $versionNo, $isRemoteId, $useAlwaysAvailable)
590
        );
591
    }
592
593
    public function internalLoadContentProvider()
594
    {
595
        return [
596
            [123, null, null, false, false],
597
            [123, null, 456, false, false],
598
            [456, null, 123, false, true],
599
            [456, null, 2, false, false],
600
            [456, ['eng-GB'], 2, false, true],
601
            [456, ['eng-GB', 'fre-FR'], null, false, false],
602
            [456, ['eng-GB', 'fre-FR', 'nor-NO'], 2, false, false],
603
            // With remoteId
604
            [123, null, null, true, false],
605
            ['someRemoteId', null, 456, true, false],
606
            [456, null, 123, true, false],
607
            ['someRemoteId', null, 2, true, false],
608
            ['someRemoteId', ['eng-GB'], 2, true, false],
609
            [456, ['eng-GB', 'fre-FR'], null, true, false],
610
            ['someRemoteId', ['eng-GB', 'fre-FR', 'nor-NO'], 2, true, false],
611
        ];
612
    }
613
614
    /**
615
     * @expectedException \eZ\Publish\Core\Base\Exceptions\NotFoundException
616
     */
617
    public function testInternalLoadContentNotFound()
618
    {
619
        $contentService = $this->getPartlyMockedContentService();
620
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
621
        $contentHandler = $this->getPersistenceMock()->contentHandler();
622
        $id = 123;
623
        $versionNo = 7;
624
        $languages = null;
625
        $contentHandler
626
            ->expects($this->once())
627
            ->method('load')
628
            ->with($id, $versionNo, $languages)
629
            ->will(
630
                $this->throwException(
631
                    $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...
632
                )
633
            );
634
635
        $contentService->internalLoadContent($id, $languages, $versionNo);
636
    }
637
638
    /**
639
     * Test for the loadContentByContentInfo() method.
640
     *
641
     * @covers \eZ\Publish\Core\Repository\ContentService::loadContentByContentInfo
642
     */
643
    public function testLoadContentByContentInfo()
644
    {
645
        $contentServiceMock = $this->getPartlyMockedContentService(
646
            ['loadContent']
647
        );
648
        $contentServiceMock->expects(
649
            $this->once()
650
        )->method(
651
            'loadContent'
652
        )->with(
653
            $this->equalTo(42),
654
            $this->equalTo(['cro-HR']),
655
            $this->equalTo(7),
656
            $this->equalTo(false)
657
        )->will(
658
            $this->returnValue('result')
659
        );
660
661
        $result = $contentServiceMock->loadContentByContentInfo(
662
            new ContentInfo(['id' => 42]),
663
            ['cro-HR'],
664
            7
665
        );
666
667
        $this->assertEquals('result', $result);
668
    }
669
670
    /**
671
     * Test for the loadContentByVersionInfo() method.
672
     *
673
     * @covers \eZ\Publish\Core\Repository\ContentService::loadContentByVersionInfo
674
     */
675
    public function testLoadContentByVersionInfo()
676
    {
677
        $contentServiceMock = $this->getPartlyMockedContentService(
678
            ['loadContent']
679
        );
680
        $contentServiceMock->expects(
681
            $this->once()
682
        )->method(
683
            'loadContent'
684
        )->with(
685
            $this->equalTo(42),
686
            $this->equalTo(['cro-HR']),
687
            $this->equalTo(7),
688
            $this->equalTo(false)
689
        )->will(
690
            $this->returnValue('result')
691
        );
692
693
        $result = $contentServiceMock->loadContentByVersionInfo(
694
            new VersionInfo(
695
                [
696
                    'contentInfo' => new ContentInfo(['id' => 42]),
697
                    'versionNo' => 7,
698
                ]
699
            ),
700
            ['cro-HR']
701
        );
702
703
        $this->assertEquals('result', $result);
704
    }
705
706
    /**
707
     * Test for the deleteContent() method.
708
     *
709
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteContent
710
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
711
     */
712
    public function testDeleteContentThrowsUnauthorizedException()
713
    {
714
        $repository = $this->getRepositoryMock();
715
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo']);
716
        $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...
717
718
        $contentInfo->expects($this->any())
719
            ->method('__get')
720
            ->with('id')
721
            ->will($this->returnValue(42));
722
723
        $contentService->expects($this->once())
724
            ->method('internalLoadContentInfo')
725
            ->with(42)
726
            ->will($this->returnValue($contentInfo));
727
728
        $repository->expects($this->once())
729
            ->method('canUser')
730
            ->with('content', 'remove')
731
            ->will($this->returnValue(false));
732
733
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */
734
        $contentService->deleteContent($contentInfo);
735
    }
736
737
    /**
738
     * Test for the deleteContent() method.
739
     *
740
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteContent
741
     */
742
    public function testDeleteContent()
743
    {
744
        $repository = $this->getRepositoryMock();
745
746
        $repository->expects($this->once())
747
            ->method('canUser')
748
            ->with('content', 'remove')
749
            ->will($this->returnValue(true));
750
751
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo']);
752
        /** @var \PHPUnit_Framework_MockObject_MockObject $urlAliasHandler */
753
        $urlAliasHandler = $this->getPersistenceMock()->urlAliasHandler();
754
        /** @var \PHPUnit_Framework_MockObject_MockObject $locationHandler */
755
        $locationHandler = $this->getPersistenceMock()->locationHandler();
756
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
757
        $contentHandler = $this->getPersistenceMock()->contentHandler();
758
759
        $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...
760
761
        $contentService->expects($this->once())
762
            ->method('internalLoadContentInfo')
763
            ->with(42)
764
            ->will($this->returnValue($contentInfo));
765
766
        $contentInfo->expects($this->any())
767
            ->method('__get')
768
            ->with('id')
769
            ->will($this->returnValue(42));
770
771
        $repository->expects($this->once())->method('beginTransaction');
772
773
        $spiLocations = [
774
            new SPILocation(['id' => 1]),
775
            new SPILocation(['id' => 2]),
776
        ];
777
        $locationHandler->expects($this->once())
778
            ->method('loadLocationsByContent')
779
            ->with(42)
780
            ->will($this->returnValue($spiLocations));
781
782
        $contentHandler->expects($this->once())
783
            ->method('deleteContent')
784
            ->with(42);
785
786
        foreach ($spiLocations as $index => $spiLocation) {
787
            $urlAliasHandler->expects($this->at($index))
788
                ->method('locationDeleted')
789
                ->with($spiLocation->id);
790
        }
791
792
        $repository->expects($this->once())->method('commit');
793
794
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */
795
        $contentService->deleteContent($contentInfo);
796
    }
797
798
    /**
799
     * Test for the deleteContent() method.
800
     *
801
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteContent
802
     * @expectedException \Exception
803
     */
804
    public function testDeleteContentWithRollback()
805
    {
806
        $repository = $this->getRepositoryMock();
807
808
        $repository->expects($this->once())
809
            ->method('canUser')
810
            ->with('content', 'remove')
811
            ->will($this->returnValue(true));
812
813
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo']);
814
        /** @var \PHPUnit_Framework_MockObject_MockObject $locationHandler */
815
        $locationHandler = $this->getPersistenceMock()->locationHandler();
816
817
        $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...
818
819
        $contentService->expects($this->once())
820
            ->method('internalLoadContentInfo')
821
            ->with(42)
822
            ->will($this->returnValue($contentInfo));
823
824
        $contentInfo->expects($this->any())
825
            ->method('__get')
826
            ->with('id')
827
            ->will($this->returnValue(42));
828
829
        $repository->expects($this->once())->method('beginTransaction');
830
831
        $locationHandler->expects($this->once())
832
            ->method('loadLocationsByContent')
833
            ->with(42)
834
            ->will($this->throwException(new \Exception()));
835
836
        $repository->expects($this->once())->method('rollback');
837
838
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */
839
        $contentService->deleteContent($contentInfo);
840
    }
841
842
    /**
843
     * Test for the deleteVersion() method.
844
     *
845
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteVersion
846
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
847
     */
848
    public function testDeleteVersionThrowsBadStateExceptionLastVersion()
849
    {
850
        $repository = $this->getRepositoryMock();
851
        $repository
852
            ->expects($this->once())
853
            ->method('canUser')
854
            ->with('content', 'versionremove')
855
            ->will($this->returnValue(true));
856
        $repository
857
            ->expects($this->never())
858
            ->method('beginTransaction');
859
860
        $contentService = $this->getPartlyMockedContentService();
861
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandler */
862
        $contentHandler = $this->getPersistenceMock()->contentHandler();
863
        $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...
864
        $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...
865
866
        $contentInfo
867
            ->expects($this->any())
868
            ->method('__get')
869
            ->with('id')
870
            ->will($this->returnValue(42));
871
872
        $versionInfo
873
            ->expects($this->any())
874
            ->method('__get')
875
            ->will(
876
                $this->returnValueMap(
877
                    [
878
                        ['versionNo', 123],
879
                        ['status', VersionInfo::STATUS_DRAFT],
880
                        ['contentInfo', $contentInfo],
881
                    ]
882
                )
883
            );
884
885
        $contentHandler
886
            ->expects($this->once())
887
            ->method('listVersions')
888
            ->with(42)
889
            ->will($this->returnValue(['version']));
890
891
        /* @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo */
892
        $contentService->deleteVersion($versionInfo);
893
    }
894
895
    /**
896
     * Test for the createContent() method.
897
     *
898
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
899
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
900
     * @expectedExceptionMessage Argument '$contentCreateStruct' is invalid: 'mainLanguageCode' property must be set
901
     */
902
    public function testCreateContentThrowsInvalidArgumentExceptionMainLanguageCodeNotSet()
903
    {
904
        $mockedService = $this->getPartlyMockedContentService();
905
        $mockedService->createContent(new ContentCreateStruct(), []);
906
    }
907
908
    /**
909
     * Test for the createContent() method.
910
     *
911
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
912
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
913
     * @expectedExceptionMessage Argument '$contentCreateStruct' is invalid: 'contentType' property must be set
914
     */
915
    public function testCreateContentThrowsInvalidArgumentExceptionContentTypeNotSet()
916
    {
917
        $mockedService = $this->getPartlyMockedContentService();
918
        $mockedService->createContent(
919
            new ContentCreateStruct(['mainLanguageCode' => 'eng-US']),
920
            []
921
        );
922
    }
923
924
    /**
925
     * Test for the createContent() method.
926
     *
927
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
928
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
929
     */
930
    public function testCreateContentThrowsUnauthorizedException()
931
    {
932
        $repositoryMock = $this->getRepositoryMock();
933
        $mockedService = $this->getPartlyMockedContentService();
934
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
935
        $contentType = new ContentType(
936
            [
937
                'id' => 123,
938
                'fieldDefinitions' => [],
939
            ]
940
        );
941
        $contentCreateStruct = new ContentCreateStruct(
942
            [
943
                'ownerId' => 169,
944
                'alwaysAvailable' => false,
945
                'mainLanguageCode' => 'eng-US',
946
                'contentType' => $contentType,
947
            ]
948
        );
949
950
        $repositoryMock->expects($this->once())
951
            ->method('getCurrentUserReference')
952
            ->will($this->returnValue(new UserReference(169)));
953
954
        $contentTypeServiceMock->expects($this->once())
955
            ->method('loadContentType')
956
            ->with($this->equalTo(123))
957
            ->will($this->returnValue($contentType));
958
959
        $repositoryMock->expects($this->once())
960
            ->method('getContentTypeService')
961
            ->will($this->returnValue($contentTypeServiceMock));
962
963
        $repositoryMock->expects($this->once())
964
            ->method('canUser')
965
            ->with(
966
                $this->equalTo('content'),
967
                $this->equalTo('create'),
968
                $this->isInstanceOf($contentCreateStruct),
969
                $this->equalTo([])
970
            )->will($this->returnValue(false));
971
972
        $mockedService->createContent(
973
            new ContentCreateStruct(
974
                [
975
                    'mainLanguageCode' => 'eng-US',
976
                    'contentType' => $contentType,
977
                ]
978
            ),
979
            []
980
        );
981
    }
982
983
    /**
984
     * Test for the createContent() method.
985
     *
986
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
987
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
988
     * @exceptionMessage Argument '$contentCreateStruct' is invalid: Another content with remoteId 'faraday' exists
989
     */
990
    public function testCreateContentThrowsInvalidArgumentExceptionDuplicateRemoteId()
991
    {
992
        $repositoryMock = $this->getRepositoryMock();
993
        $mockedService = $this->getPartlyMockedContentService(['loadContentByRemoteId']);
994
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
995
        $contentType = new ContentType(
996
            [
997
                'id' => 123,
998
                'fieldDefinitions' => [],
999
            ]
1000
        );
1001
        $contentCreateStruct = new ContentCreateStruct(
1002
            [
1003
                'ownerId' => 169,
1004
                'alwaysAvailable' => false,
1005
                'remoteId' => 'faraday',
1006
                'mainLanguageCode' => 'eng-US',
1007
                'contentType' => $contentType,
1008
            ]
1009
        );
1010
1011
        $repositoryMock->expects($this->once())
1012
            ->method('getCurrentUserReference')
1013
            ->will($this->returnValue(new UserReference(169)));
1014
1015
        $contentTypeServiceMock->expects($this->once())
1016
            ->method('loadContentType')
1017
            ->with($this->equalTo(123))
1018
            ->will($this->returnValue($contentType));
1019
1020
        $repositoryMock->expects($this->once())
1021
            ->method('getContentTypeService')
1022
            ->will($this->returnValue($contentTypeServiceMock));
1023
1024
        $repositoryMock->expects($this->once())
1025
            ->method('canUser')
1026
            ->with(
1027
                $this->equalTo('content'),
1028
                $this->equalTo('create'),
1029
                $this->isInstanceOf($contentCreateStruct),
1030
                $this->equalTo([])
1031
            )->will($this->returnValue(true));
1032
1033
        $mockedService->expects($this->once())
1034
            ->method('loadContentByRemoteId')
1035
            ->with($contentCreateStruct->remoteId)
1036
            ->will($this->returnValue('Hello...'));
1037
1038
        $mockedService->createContent(
1039
            new ContentCreateStruct(
1040
                [
1041
                    'remoteId' => 'faraday',
1042
                    'mainLanguageCode' => 'eng-US',
1043
                    'contentType' => $contentType,
1044
                ]
1045
            ),
1046
            []
1047
        );
1048
    }
1049
1050
    /**
1051
     * @param string $mainLanguageCode
1052
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
1053
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
1054
     *
1055
     * @return array
1056
     */
1057
    protected function mapStructFieldsForCreate($mainLanguageCode, $structFields, $fieldDefinitions)
1058
    {
1059
        $mappedFieldDefinitions = [];
1060
        foreach ($fieldDefinitions as $fieldDefinition) {
1061
            $mappedFieldDefinitions[$fieldDefinition->identifier] = $fieldDefinition;
1062
        }
1063
1064
        $mappedStructFields = [];
1065
        foreach ($structFields as $structField) {
1066
            if ($structField->languageCode === null) {
1067
                $languageCode = $mainLanguageCode;
1068
            } else {
1069
                $languageCode = $structField->languageCode;
1070
            }
1071
1072
            $mappedStructFields[$structField->fieldDefIdentifier][$languageCode] = (string)$structField->value;
1073
        }
1074
1075
        return $mappedStructFields;
1076
    }
1077
1078
    /**
1079
     * Returns full, possibly redundant array of field values, indexed by field definition
1080
     * identifier and language code.
1081
     *
1082
     * @throws \RuntimeException Method is intended to be used only with consistent fixtures
1083
     *
1084
     * @param string $mainLanguageCode
1085
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
1086
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
1087
     * @param array $languageCodes
1088
     *
1089
     * @return array
1090
     */
1091
    protected function determineValuesForCreate(
1092
        $mainLanguageCode,
1093
        array $structFields,
1094
        array $fieldDefinitions,
1095
        array $languageCodes
1096
    ) {
1097
        $mappedStructFields = $this->mapStructFieldsForCreate(
1098
            $mainLanguageCode,
1099
            $structFields,
1100
            $fieldDefinitions
1101
        );
1102
1103
        $values = [];
1104
1105
        foreach ($fieldDefinitions as $fieldDefinition) {
1106
            $identifier = $fieldDefinition->identifier;
1107
            foreach ($languageCodes as $languageCode) {
1108 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...
1109
                    if (isset($mappedStructFields[$identifier][$mainLanguageCode])) {
1110
                        $values[$identifier][$languageCode] = $mappedStructFields[$identifier][$mainLanguageCode];
1111
                    } else {
1112
                        $values[$identifier][$languageCode] = (string)$fieldDefinition->defaultValue;
1113
                    }
1114
                    continue;
1115
                }
1116
1117 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...
1118
                    $values[$identifier][$languageCode] = $mappedStructFields[$identifier][$languageCode];
1119
                    continue;
1120
                }
1121
1122
                $values[$identifier][$languageCode] = (string)$fieldDefinition->defaultValue;
1123
            }
1124
        }
1125
1126
        return $this->stubValues($values);
1127
    }
1128
1129
    /**
1130
     * @param string $mainLanguageCode
1131
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
1132
     *
1133
     * @return string[]
1134
     */
1135 View Code Duplication
    protected function determineLanguageCodesForCreate($mainLanguageCode, array $structFields)
1136
    {
1137
        $languageCodes = [];
1138
1139
        foreach ($structFields as $field) {
1140
            if ($field->languageCode === null || isset($languageCodes[$field->languageCode])) {
1141
                continue;
1142
            }
1143
1144
            $languageCodes[$field->languageCode] = true;
1145
        }
1146
1147
        $languageCodes[$mainLanguageCode] = true;
1148
1149
        return array_keys($languageCodes);
1150
    }
1151
1152
    /**
1153
     * Asserts that calling createContent() with given API field set causes calling
1154
     * Handler::createContent() with given SPI field set.
1155
     *
1156
     * @param string $mainLanguageCode
1157
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
1158
     * @param \eZ\Publish\SPI\Persistence\Content\Field[] $spiFields
1159
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
1160
     * @param \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct[] $locationCreateStructs
1161
     * @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...
1162
     * @param bool $execute
1163
     *
1164
     * @return mixed
1165
     */
1166
    protected function assertForTestCreateContentNonRedundantFieldSet(
1167
        $mainLanguageCode,
1168
        array $structFields,
1169
        array $spiFields,
1170
        array $fieldDefinitions,
1171
        array $locationCreateStructs = [],
1172
        $withObjectStates = false,
1173
        $execute = true
1174
    ) {
1175
        $repositoryMock = $this->getRepositoryMock();
1176
        $mockedService = $this->getPartlyMockedContentService();
1177
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
1178
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
1179
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
1180
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
1181
        /** @var \PHPUnit_Framework_MockObject_MockObject $objectStateHandlerMock */
1182
        $objectStateHandlerMock = $this->getPersistenceMock()->objectStateHandler();
1183
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
1184
        $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...
1185
        $domainMapperMock = $this->getDomainMapperMock();
1186
        $relationProcessorMock = $this->getRelationProcessorMock();
1187
        $nameSchemaServiceMock = $this->getNameSchemaServiceMock();
1188
        $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...
1189
        $languageCodes = $this->determineLanguageCodesForCreate($mainLanguageCode, $structFields);
1190
        $contentType = new ContentType(
1191
            [
1192
                'id' => 123,
1193
                'fieldDefinitions' => $fieldDefinitions,
1194
                'nameSchema' => '<nameSchema>',
1195
            ]
1196
        );
1197
        $contentCreateStruct = new ContentCreateStruct(
1198
            [
1199
                'fields' => $structFields,
1200
                'mainLanguageCode' => $mainLanguageCode,
1201
                'contentType' => $contentType,
1202
                'alwaysAvailable' => false,
1203
                'ownerId' => 169,
1204
                'sectionId' => 1,
1205
            ]
1206
        );
1207
1208
        $languageHandlerMock->expects($this->any())
1209
            ->method('loadByLanguageCode')
1210
            ->with($this->isType('string'))
1211
            ->will(
1212
                $this->returnCallback(
1213
                    function () {
1214
                        return new Language(['id' => 4242]);
1215
                    }
1216
                )
1217
            );
1218
1219
        $repositoryMock->expects($this->once())->method('beginTransaction');
1220
1221
        $contentTypeServiceMock->expects($this->once())
1222
            ->method('loadContentType')
1223
            ->with($this->equalTo($contentType->id))
1224
            ->will($this->returnValue($contentType));
1225
1226
        $repositoryMock->expects($this->once())
1227
            ->method('getContentTypeService')
1228
            ->will($this->returnValue($contentTypeServiceMock));
1229
1230
        $that = $this;
1231
        $repositoryMock->expects($this->once())
1232
            ->method('canUser')
1233
            ->with(
1234
                $this->equalTo('content'),
1235
                $this->equalTo('create'),
1236
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
1237
                $this->equalTo($locationCreateStructs)
1238
            )->will(
1239
                $this->returnCallback(
1240
                    function () use ($that, $contentCreateStruct) {
1241
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
1242
1243
                        return true;
1244
                    }
1245
                )
1246
            );
1247
1248
        $domainMapperMock->expects($this->once())
1249
            ->method('getUniqueHash')
1250
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
1251
            ->will(
1252
                $this->returnCallback(
1253
                    function ($object) use ($that, $contentCreateStruct) {
1254
                        $that->assertEquals($contentCreateStruct, $object);
1255
1256
                        return 'hash';
1257
                    }
1258
                )
1259
            );
1260
1261
        $fieldTypeMock->expects($this->any())
1262
            ->method('acceptValue')
1263
            ->will(
1264
                $this->returnCallback(
1265
                    function ($valueString) {
1266
                        return new ValueStub($valueString);
1267
                    }
1268
                )
1269
            );
1270
1271
        $fieldTypeMock->expects($this->any())
1272
            ->method('toPersistenceValue')
1273
            ->will(
1274
                $this->returnCallback(
1275
                    function (ValueStub $value) {
1276
                        return (string)$value;
1277
                    }
1278
                )
1279
            );
1280
1281
        $emptyValue = self::EMPTY_FIELD_VALUE;
1282
        $fieldTypeMock->expects($this->any())
1283
            ->method('isEmptyValue')
1284
            ->will(
1285
                $this->returnCallback(
1286
                    function (ValueStub $value) use ($emptyValue) {
1287
                        return $emptyValue === (string)$value;
1288
                    }
1289
                )
1290
            );
1291
1292
        $fieldTypeMock->expects($this->any())
1293
            ->method('validate')
1294
            ->will($this->returnValue([]));
1295
1296
        $this->getFieldTypeRegistryMock()->expects($this->any())
1297
            ->method('getFieldType')
1298
            ->will($this->returnValue($fieldTypeMock));
1299
1300
        $relationProcessorMock
1301
            ->expects($this->exactly(count($fieldDefinitions) * count($languageCodes)))
1302
            ->method('appendFieldRelations')
1303
            ->with(
1304
                $this->isType('array'),
1305
                $this->isType('array'),
1306
                $this->isInstanceOf('eZ\\Publish\\SPI\\FieldType\\FieldType'),
1307
                $this->isInstanceOf('eZ\\Publish\\Core\\FieldType\\Value'),
1308
                $this->anything()
1309
            );
1310
1311
        $values = $this->determineValuesForCreate(
1312
            $mainLanguageCode,
1313
            $structFields,
1314
            $fieldDefinitions,
1315
            $languageCodes
1316
        );
1317
        $nameSchemaServiceMock->expects($this->once())
1318
            ->method('resolve')
1319
            ->with(
1320
                $this->equalTo($contentType->nameSchema),
1321
                $this->equalTo($contentType),
1322
                $this->equalTo($values),
1323
                $this->equalTo($languageCodes)
1324
            )->will($this->returnValue([]));
1325
1326
        $relationProcessorMock->expects($this->any())
1327
            ->method('processFieldRelations')
1328
            ->with(
1329
                $this->isType('array'),
1330
                $this->equalTo(42),
1331
                $this->isType('int'),
1332
                $this->equalTo($contentType),
1333
                $this->equalTo([])
1334
            );
1335
1336
        if (!$withObjectStates) {
1337
            $objectStateHandlerMock->expects($this->once())
1338
                ->method('loadAllGroups')
1339
                ->will($this->returnValue([]));
1340
        }
1341
1342
        if ($execute) {
1343
            $spiContentCreateStruct = new SPIContentCreateStruct(
1344
                [
1345
                    'name' => [],
1346
                    'typeId' => 123,
1347
                    'sectionId' => 1,
1348
                    'ownerId' => 169,
1349
                    'remoteId' => 'hash',
1350
                    'fields' => $spiFields,
1351
                    'modified' => time(),
1352
                    'initialLanguageId' => 4242,
1353
                ]
1354
            );
1355
            $spiContentCreateStruct2 = clone $spiContentCreateStruct;
1356
            ++$spiContentCreateStruct2->modified;
1357
1358
            $spiContent = new SPIContent(
1359
                [
1360
                    'versionInfo' => new SPIContent\VersionInfo(
1361
                        [
1362
                            'contentInfo' => new SPIContent\ContentInfo(['id' => 42]),
1363
                            'versionNo' => 7,
1364
                        ]
1365
                    ),
1366
                ]
1367
            );
1368
1369
            $contentHandlerMock->expects($this->once())
1370
                ->method('create')
1371
                ->with($this->logicalOr($spiContentCreateStruct, $spiContentCreateStruct2))
1372
                ->will($this->returnValue($spiContent));
1373
1374
            $repositoryMock->expects($this->once())->method('commit');
1375
            $domainMapperMock->expects($this->once())
1376
                ->method('buildContentDomainObject')
1377
                ->with(
1378
                    $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content'),
1379
                    $this->equalTo(null)
1380
                );
1381
1382
            $mockedService->createContent($contentCreateStruct, []);
1383
        }
1384
1385
        return $contentCreateStruct;
1386
    }
1387
1388
    public function providerForTestCreateContentNonRedundantFieldSet1()
1389
    {
1390
        $spiFields = [
1391
            new SPIField(
1392
                [
1393
                    'fieldDefinitionId' => 'fieldDefinitionId',
1394
                    'type' => 'fieldTypeIdentifier',
1395
                    'value' => 'newValue',
1396
                    'languageCode' => 'eng-US',
1397
                ]
1398
            ),
1399
        ];
1400
1401
        return [
1402
            // 0. Without language set
1403
            [
1404
                'eng-US',
1405
                [
1406
                    new Field(
1407
                        [
1408
                            'fieldDefIdentifier' => 'identifier',
1409
                            'value' => 'newValue',
1410
                            'languageCode' => 'eng-US',
1411
                        ]
1412
                    ),
1413
                ],
1414
                $spiFields,
1415
            ],
1416
            // 1. Without language set
1417
            [
1418
                'eng-US',
1419
                [
1420
                    new Field(
1421
                        [
1422
                            'fieldDefIdentifier' => 'identifier',
1423
                            'value' => 'newValue',
1424
                            'languageCode' => null,
1425
                        ]
1426
                    ),
1427
                ],
1428
                $spiFields,
1429
            ],
1430
        ];
1431
    }
1432
1433
    /**
1434
     * Test for the createContent() method.
1435
     *
1436
     * Testing the simplest use case.
1437
     *
1438
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1439
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
1440
     * @covers \eZ\Publish\Core\Repository\ContentService::cloneField
1441
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
1442
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1443
     * @dataProvider providerForTestCreateContentNonRedundantFieldSet1
1444
     */
1445 View Code Duplication
    public function testCreateContentNonRedundantFieldSet1($mainLanguageCode, $structFields, $spiFields)
1446
    {
1447
        $fieldDefinitions = [
1448
            new FieldDefinition(
1449
                [
1450
                    'id' => 'fieldDefinitionId',
1451
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1452
                    'isTranslatable' => false,
1453
                    'identifier' => 'identifier',
1454
                    'isRequired' => false,
1455
                    'defaultValue' => 'defaultValue',
1456
                ]
1457
            ),
1458
        ];
1459
1460
        $this->assertForTestCreateContentNonRedundantFieldSet(
1461
            $mainLanguageCode,
1462
            $structFields,
1463
            $spiFields,
1464
            $fieldDefinitions
1465
        );
1466
    }
1467
1468
    public function providerForTestCreateContentNonRedundantFieldSet2()
1469
    {
1470
        $spiFields = [
1471
            new SPIField(
1472
                [
1473
                    'fieldDefinitionId' => 'fieldDefinitionId1',
1474
                    'type' => 'fieldTypeIdentifier',
1475
                    'value' => 'newValue1',
1476
                    'languageCode' => 'eng-US',
1477
                ]
1478
            ),
1479
            new SPIField(
1480
                [
1481
                    'fieldDefinitionId' => 'fieldDefinitionId2',
1482
                    'type' => 'fieldTypeIdentifier',
1483
                    'value' => 'newValue2',
1484
                    'languageCode' => 'ger-DE',
1485
                ]
1486
            ),
1487
        ];
1488
1489
        return [
1490
            // 0. With language set
1491
            [
1492
                'eng-US',
1493
                [
1494
                    new Field(
1495
                        [
1496
                            'fieldDefIdentifier' => 'identifier1',
1497
                            'value' => 'newValue1',
1498
                            'languageCode' => 'eng-US',
1499
                        ]
1500
                    ),
1501
                    new Field(
1502
                        [
1503
                            'fieldDefIdentifier' => 'identifier2',
1504
                            'value' => 'newValue2',
1505
                            'languageCode' => 'ger-DE',
1506
                        ]
1507
                    ),
1508
                ],
1509
                $spiFields,
1510
            ],
1511
            // 1. Without language set
1512
            [
1513
                'eng-US',
1514
                [
1515
                    new Field(
1516
                        [
1517
                            'fieldDefIdentifier' => 'identifier1',
1518
                            'value' => 'newValue1',
1519
                            'languageCode' => null,
1520
                        ]
1521
                    ),
1522
                    new Field(
1523
                        [
1524
                            'fieldDefIdentifier' => 'identifier2',
1525
                            'value' => 'newValue2',
1526
                            'languageCode' => 'ger-DE',
1527
                        ]
1528
                    ),
1529
                ],
1530
                $spiFields,
1531
            ],
1532
        ];
1533
    }
1534
1535
    /**
1536
     * Test for the createContent() method.
1537
     *
1538
     * Testing multiple languages with multiple translatable fields with empty default value.
1539
     *
1540
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1541
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
1542
     * @covers \eZ\Publish\Core\Repository\ContentService::cloneField
1543
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
1544
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1545
     * @dataProvider providerForTestCreateContentNonRedundantFieldSet2
1546
     */
1547
    public function testCreateContentNonRedundantFieldSet2($mainLanguageCode, $structFields, $spiFields)
1548
    {
1549
        $fieldDefinitions = [
1550
            new FieldDefinition(
1551
                [
1552
                    'id' => 'fieldDefinitionId1',
1553
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1554
                    'isTranslatable' => true,
1555
                    'identifier' => 'identifier1',
1556
                    'isRequired' => false,
1557
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
1558
                ]
1559
            ),
1560
            new FieldDefinition(
1561
                [
1562
                    'id' => 'fieldDefinitionId2',
1563
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1564
                    'isTranslatable' => true,
1565
                    'identifier' => 'identifier2',
1566
                    'isRequired' => false,
1567
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
1568
                ]
1569
            ),
1570
        ];
1571
1572
        $this->assertForTestCreateContentNonRedundantFieldSet(
1573
            $mainLanguageCode,
1574
            $structFields,
1575
            $spiFields,
1576
            $fieldDefinitions
1577
        );
1578
    }
1579
1580
    public function providerForTestCreateContentNonRedundantFieldSetComplex()
1581
    {
1582
        $spiFields0 = [
1583
            new SPIField(
1584
                [
1585
                    'fieldDefinitionId' => 'fieldDefinitionId2',
1586
                    'type' => 'fieldTypeIdentifier',
1587
                    'value' => 'defaultValue2',
1588
                    'languageCode' => 'eng-US',
1589
                ]
1590
            ),
1591
            new SPIField(
1592
                [
1593
                    'fieldDefinitionId' => 'fieldDefinitionId4',
1594
                    'type' => 'fieldTypeIdentifier',
1595
                    'value' => 'defaultValue4',
1596
                    'languageCode' => 'eng-US',
1597
                ]
1598
            ),
1599
        ];
1600
        $spiFields1 = [
1601
            new SPIField(
1602
                [
1603
                    'fieldDefinitionId' => 'fieldDefinitionId1',
1604
                    'type' => 'fieldTypeIdentifier',
1605
                    'value' => 'newValue1',
1606
                    'languageCode' => 'ger-DE',
1607
                ]
1608
            ),
1609
            new SPIField(
1610
                [
1611
                    'fieldDefinitionId' => 'fieldDefinitionId2',
1612
                    'type' => 'fieldTypeIdentifier',
1613
                    'value' => 'defaultValue2',
1614
                    'languageCode' => 'ger-DE',
1615
                ]
1616
            ),
1617
            new SPIField(
1618
                [
1619
                    'fieldDefinitionId' => 'fieldDefinitionId2',
1620
                    'type' => 'fieldTypeIdentifier',
1621
                    'value' => 'newValue2',
1622
                    'languageCode' => 'eng-US',
1623
                ]
1624
            ),
1625
            new SPIField(
1626
                [
1627
                    'fieldDefinitionId' => 'fieldDefinitionId4',
1628
                    'type' => 'fieldTypeIdentifier',
1629
                    'value' => 'newValue4',
1630
                    'languageCode' => 'eng-US',
1631
                ]
1632
            ),
1633
        ];
1634
1635
        return [
1636
            // 0. Creating by default values only
1637
            [
1638
                'eng-US',
1639
                [],
1640
                $spiFields0,
1641
            ],
1642
            // 1. Multiple languages with language set
1643
            [
1644
                'eng-US',
1645
                [
1646
                    new Field(
1647
                        [
1648
                            'fieldDefIdentifier' => 'identifier1',
1649
                            'value' => 'newValue1',
1650
                            'languageCode' => 'ger-DE',
1651
                        ]
1652
                    ),
1653
                    new Field(
1654
                        [
1655
                            'fieldDefIdentifier' => 'identifier2',
1656
                            'value' => 'newValue2',
1657
                            'languageCode' => 'eng-US',
1658
                        ]
1659
                    ),
1660
                    new Field(
1661
                        [
1662
                            'fieldDefIdentifier' => 'identifier4',
1663
                            'value' => 'newValue4',
1664
                            'languageCode' => 'eng-US',
1665
                        ]
1666
                    ),
1667
                ],
1668
                $spiFields1,
1669
            ],
1670
            // 2. Multiple languages without language set
1671
            [
1672
                'eng-US',
1673
                [
1674
                    new Field(
1675
                        [
1676
                            'fieldDefIdentifier' => 'identifier1',
1677
                            'value' => 'newValue1',
1678
                            'languageCode' => 'ger-DE',
1679
                        ]
1680
                    ),
1681
                    new Field(
1682
                        [
1683
                            'fieldDefIdentifier' => 'identifier2',
1684
                            'value' => 'newValue2',
1685
                            'languageCode' => null,
1686
                        ]
1687
                    ),
1688
                    new Field(
1689
                        [
1690
                            'fieldDefIdentifier' => 'identifier4',
1691
                            'value' => 'newValue4',
1692
                            'languageCode' => null,
1693
                        ]
1694
                    ),
1695
                ],
1696
                $spiFields1,
1697
            ],
1698
        ];
1699
    }
1700
1701
    protected function fixturesForTestCreateContentNonRedundantFieldSetComplex()
1702
    {
1703
        return [
1704
            new FieldDefinition(
1705
                [
1706
                    'id' => 'fieldDefinitionId1',
1707
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1708
                    'isTranslatable' => true,
1709
                    'identifier' => 'identifier1',
1710
                    'isRequired' => false,
1711
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
1712
                ]
1713
            ),
1714
            new FieldDefinition(
1715
                [
1716
                    'id' => 'fieldDefinitionId2',
1717
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1718
                    'isTranslatable' => true,
1719
                    'identifier' => 'identifier2',
1720
                    'isRequired' => false,
1721
                    'defaultValue' => 'defaultValue2',
1722
                ]
1723
            ),
1724
            new FieldDefinition(
1725
                [
1726
                    'id' => 'fieldDefinitionId3',
1727
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1728
                    'isTranslatable' => false,
1729
                    'identifier' => 'identifier3',
1730
                    'isRequired' => false,
1731
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
1732
                ]
1733
            ),
1734
            new FieldDefinition(
1735
                [
1736
                    'id' => 'fieldDefinitionId4',
1737
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
1738
                    'isTranslatable' => false,
1739
                    'identifier' => 'identifier4',
1740
                    'isRequired' => false,
1741
                    'defaultValue' => 'defaultValue4',
1742
                ]
1743
            ),
1744
        ];
1745
    }
1746
1747
    /**
1748
     * Test for the createContent() method.
1749
     *
1750
     * Testing multiple languages with multiple translatable fields with empty default value.
1751
     *
1752
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1753
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
1754
     * @covers \eZ\Publish\Core\Repository\ContentService::cloneField
1755
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
1756
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1757
     * @dataProvider providerForTestCreateContentNonRedundantFieldSetComplex
1758
     */
1759
    public function testCreateContentNonRedundantFieldSetComplex($mainLanguageCode, $structFields, $spiFields)
1760
    {
1761
        $fieldDefinitions = $this->fixturesForTestCreateContentNonRedundantFieldSetComplex();
1762
1763
        $this->assertForTestCreateContentNonRedundantFieldSet(
1764
            $mainLanguageCode,
1765
            $structFields,
1766
            $spiFields,
1767
            $fieldDefinitions
1768
        );
1769
    }
1770
1771 View Code Duplication
    public function providerForTestCreateContentWithInvalidLanguage()
1772
    {
1773
        return [
1774
            [
1775
                'eng-GB',
1776
                [
1777
                    new Field(
1778
                        [
1779
                            'fieldDefIdentifier' => 'identifier',
1780
                            'value' => 'newValue',
1781
                            'languageCode' => 'Klingon',
1782
                        ]
1783
                    ),
1784
                ],
1785
            ],
1786
            [
1787
                'Klingon',
1788
                [
1789
                    new Field(
1790
                        [
1791
                            'fieldDefIdentifier' => 'identifier',
1792
                            'value' => 'newValue',
1793
                            'languageCode' => 'eng-GB',
1794
                        ]
1795
                    ),
1796
                ],
1797
            ],
1798
        ];
1799
    }
1800
1801
    /**
1802
     * Test for the updateContent() method.
1803
     *
1804
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1805
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1806
     * @dataProvider providerForTestCreateContentWithInvalidLanguage
1807
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1808
     * @expectedExceptionMessage Could not find 'Language' with identifier 'Klingon'
1809
     */
1810
    public function testCreateContentWithInvalidLanguage($mainLanguageCode, $structFields)
1811
    {
1812
        $repositoryMock = $this->getRepositoryMock();
1813
        $mockedService = $this->getPartlyMockedContentService();
1814
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
1815
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
1816
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
1817
        $domainMapperMock = $this->getDomainMapperMock();
1818
        $contentType = new ContentType(
1819
            [
1820
                'id' => 123,
1821
                'fieldDefinitions' => [],
1822
            ]
1823
        );
1824
        $contentCreateStruct = new ContentCreateStruct(
1825
            [
1826
                'fields' => $structFields,
1827
                'mainLanguageCode' => $mainLanguageCode,
1828
                'contentType' => $contentType,
1829
                'alwaysAvailable' => false,
1830
                'ownerId' => 169,
1831
                'sectionId' => 1,
1832
            ]
1833
        );
1834
1835
        $languageHandlerMock->expects($this->any())
1836
            ->method('loadByLanguageCode')
1837
            ->with($this->isType('string'))
1838
            ->will(
1839
                $this->returnCallback(
1840 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...
1841
                        if ($languageCode === 'Klingon') {
1842
                            throw new NotFoundException('Language', 'Klingon');
1843
                        }
1844
1845
                        return new Language(['id' => 4242]);
1846
                    }
1847
                )
1848
            );
1849
1850
        $contentTypeServiceMock->expects($this->once())
1851
            ->method('loadContentType')
1852
            ->with($this->equalTo($contentType->id))
1853
            ->will($this->returnValue($contentType));
1854
1855
        $repositoryMock->expects($this->once())
1856
            ->method('getContentTypeService')
1857
            ->will($this->returnValue($contentTypeServiceMock));
1858
1859
        $that = $this;
1860
        $repositoryMock->expects($this->once())
1861
            ->method('canUser')
1862
            ->with(
1863
                $this->equalTo('content'),
1864
                $this->equalTo('create'),
1865
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
1866
                $this->equalTo([])
1867
            )->will(
1868
                $this->returnCallback(
1869
                    function () use ($that, $contentCreateStruct) {
1870
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
1871
1872
                        return true;
1873
                    }
1874
                )
1875
            );
1876
1877
        $domainMapperMock->expects($this->once())
1878
            ->method('getUniqueHash')
1879
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
1880
            ->will(
1881
                $this->returnCallback(
1882
                    function ($object) use ($that, $contentCreateStruct) {
1883
                        $that->assertEquals($contentCreateStruct, $object);
1884
1885
                        return 'hash';
1886
                    }
1887
                )
1888
            );
1889
1890
        $mockedService->createContent($contentCreateStruct, []);
1891
    }
1892
1893
    protected function assertForCreateContentContentValidationException(
1894
        $mainLanguageCode,
1895
        $structFields,
1896
        $fieldDefinitions = []
1897
    ) {
1898
        $repositoryMock = $this->getRepositoryMock();
1899
        $mockedService = $this->getPartlyMockedContentService(['loadContentByRemoteId']);
1900
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
1901
        $contentType = new ContentType(
1902
            [
1903
                'id' => 123,
1904
                'fieldDefinitions' => $fieldDefinitions,
1905
            ]
1906
        );
1907
        $contentCreateStruct = new ContentCreateStruct(
1908
            [
1909
                'ownerId' => 169,
1910
                'alwaysAvailable' => false,
1911
                'remoteId' => 'faraday',
1912
                'mainLanguageCode' => $mainLanguageCode,
1913
                'fields' => $structFields,
1914
                'contentType' => $contentType,
1915
            ]
1916
        );
1917
1918
        $contentTypeServiceMock->expects($this->once())
1919
            ->method('loadContentType')
1920
            ->with($this->equalTo(123))
1921
            ->will($this->returnValue($contentType));
1922
1923
        $repositoryMock->expects($this->once())
1924
            ->method('getContentTypeService')
1925
            ->will($this->returnValue($contentTypeServiceMock));
1926
1927
        $repositoryMock->expects($this->once())
1928
            ->method('canUser')
1929
            ->with(
1930
                $this->equalTo('content'),
1931
                $this->equalTo('create'),
1932
                $this->isInstanceOf($contentCreateStruct),
1933
                $this->equalTo([])
1934
            )->will($this->returnValue(true));
1935
1936
        $mockedService->expects($this->once())
1937
            ->method('loadContentByRemoteId')
1938
            ->with($contentCreateStruct->remoteId)
1939
            ->will(
1940
                $this->throwException(new NotFoundException('Content', 'faraday'))
1941
            );
1942
1943
        $mockedService->createContent($contentCreateStruct, []);
1944
    }
1945
1946 View Code Duplication
    public function providerForTestCreateContentThrowsContentValidationExceptionFieldDefinition()
1947
    {
1948
        return [
1949
            [
1950
                'eng-GB',
1951
                [
1952
                    new Field(
1953
                        [
1954
                            'fieldDefIdentifier' => 'identifier',
1955
                            'value' => 'newValue',
1956
                            'languageCode' => 'eng-GB',
1957
                        ]
1958
                    ),
1959
                ],
1960
            ],
1961
        ];
1962
    }
1963
1964
    /**
1965
     * Test for the createContent() method.
1966
     *
1967
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
1968
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
1969
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
1970
     * @dataProvider providerForTestCreateContentThrowsContentValidationExceptionFieldDefinition
1971
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentValidationException
1972
     * @expectedExceptionMessage Field definition 'identifier' does not exist in given ContentType
1973
     */
1974
    public function testCreateContentThrowsContentValidationExceptionFieldDefinition($mainLanguageCode, $structFields)
1975
    {
1976
        $this->assertForCreateContentContentValidationException(
1977
            $mainLanguageCode,
1978
            $structFields,
1979
            []
1980
        );
1981
    }
1982
1983 View Code Duplication
    public function providerForTestCreateContentThrowsContentValidationExceptionTranslation()
1984
    {
1985
        return [
1986
            [
1987
                'eng-GB',
1988
                [
1989
                    new Field(
1990
                        [
1991
                            'fieldDefIdentifier' => 'identifier',
1992
                            'value' => 'newValue',
1993
                            'languageCode' => 'eng-US',
1994
                        ]
1995
                    ),
1996
                ],
1997
            ],
1998
        ];
1999
    }
2000
2001
    /**
2002
     * Test for the createContent() method.
2003
     *
2004
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2005
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2006
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2007
     * @dataProvider providerForTestCreateContentThrowsContentValidationExceptionTranslation
2008
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentValidationException
2009
     * @expectedExceptionMessage A value is set for non translatable field definition 'identifier' with language 'eng-US'
2010
     */
2011 View Code Duplication
    public function testCreateContentThrowsContentValidationExceptionTranslation($mainLanguageCode, $structFields)
2012
    {
2013
        $fieldDefinitions = [
2014
            new FieldDefinition(
2015
                [
2016
                    'id' => 'fieldDefinitionId1',
2017
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2018
                    'isTranslatable' => false,
2019
                    'identifier' => 'identifier',
2020
                    'isRequired' => false,
2021
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
2022
                ]
2023
            ),
2024
        ];
2025
2026
        $this->assertForCreateContentContentValidationException(
2027
            $mainLanguageCode,
2028
            $structFields,
2029
            $fieldDefinitions
2030
        );
2031
    }
2032
2033
    /**
2034
     * Asserts behaviour necessary for testing ContentFieldValidationException because of required
2035
     * field being empty.
2036
     *
2037
     * @param string $mainLanguageCode
2038
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2039
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
2040
     *
2041
     * @return mixed
2042
     */
2043
    protected function assertForTestCreateContentRequiredField(
2044
        $mainLanguageCode,
2045
        array $structFields,
2046
        array $fieldDefinitions
2047
    ) {
2048
        $repositoryMock = $this->getRepositoryMock();
2049
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
2050
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
2051
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
2052
        $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...
2053
        $domainMapperMock = $this->getDomainMapperMock();
2054
        $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...
2055
        $contentType = new ContentType(
2056
            [
2057
                'id' => 123,
2058
                'fieldDefinitions' => $fieldDefinitions,
2059
                'nameSchema' => '<nameSchema>',
2060
            ]
2061
        );
2062
        $contentCreateStruct = new ContentCreateStruct(
2063
            [
2064
                'fields' => $structFields,
2065
                'mainLanguageCode' => $mainLanguageCode,
2066
                'contentType' => $contentType,
2067
                'alwaysAvailable' => false,
2068
                'ownerId' => 169,
2069
                'sectionId' => 1,
2070
            ]
2071
        );
2072
2073
        $languageHandlerMock->expects($this->any())
2074
            ->method('loadByLanguageCode')
2075
            ->with($this->isType('string'))
2076
            ->will(
2077
                $this->returnCallback(
2078
                    function () {
2079
                        return new Language(['id' => 4242]);
2080
                    }
2081
                )
2082
            );
2083
2084
        $contentTypeServiceMock->expects($this->once())
2085
            ->method('loadContentType')
2086
            ->with($this->equalTo($contentType->id))
2087
            ->will($this->returnValue($contentType));
2088
2089
        $repositoryMock->expects($this->once())
2090
            ->method('getContentTypeService')
2091
            ->will($this->returnValue($contentTypeServiceMock));
2092
2093
        $that = $this;
2094
        $repositoryMock->expects($this->once())
2095
            ->method('canUser')
2096
            ->with(
2097
                $this->equalTo('content'),
2098
                $this->equalTo('create'),
2099
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
2100
                $this->equalTo([])
2101
            )->will(
2102
                $this->returnCallback(
2103
                    function () use ($that, $contentCreateStruct) {
2104
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
2105
2106
                        return true;
2107
                    }
2108
                )
2109
            );
2110
2111
        $domainMapperMock->expects($this->once())
2112
            ->method('getUniqueHash')
2113
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
2114
            ->will(
2115
                $this->returnCallback(
2116
                    function ($object) use ($that, $contentCreateStruct) {
2117
                        $that->assertEquals($contentCreateStruct, $object);
2118
2119
                        return 'hash';
2120
                    }
2121
                )
2122
            );
2123
2124
        $fieldTypeMock->expects($this->any())
2125
            ->method('acceptValue')
2126
            ->will(
2127
                $this->returnCallback(
2128
                    function ($valueString) {
2129
                        return new ValueStub($valueString);
2130
                    }
2131
                )
2132
            );
2133
2134
        $emptyValue = self::EMPTY_FIELD_VALUE;
2135
        $fieldTypeMock->expects($this->any())
2136
            ->method('isEmptyValue')
2137
            ->will(
2138
                $this->returnCallback(
2139
                    function (ValueStub $value) use ($emptyValue) {
2140
                        return $emptyValue === (string)$value;
2141
                    }
2142
                )
2143
            );
2144
2145
        $fieldTypeMock->expects($this->any())
2146
            ->method('validate')
2147
            ->will($this->returnValue([]));
2148
2149
        $this->getFieldTypeRegistryMock()->expects($this->any())
2150
            ->method('getFieldType')
2151
            ->will($this->returnValue($fieldTypeMock));
2152
2153
        return $contentCreateStruct;
2154
    }
2155
2156 View Code Duplication
    public function providerForTestCreateContentThrowsContentValidationExceptionRequiredField()
2157
    {
2158
        return [
2159
            [
2160
                'eng-US',
2161
                [
2162
                    new Field(
2163
                        [
2164
                            'fieldDefIdentifier' => 'identifier',
2165
                            'value' => self::EMPTY_FIELD_VALUE,
2166
                            'languageCode' => null,
2167
                        ]
2168
                    ),
2169
                ],
2170
                'identifier',
2171
                'eng-US',
2172
            ],
2173
        ];
2174
    }
2175
2176
    /**
2177
     * Test for the createContent() method.
2178
     *
2179
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2180
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2181
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2182
     * @dataProvider providerForTestCreateContentThrowsContentValidationExceptionRequiredField
2183
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
2184
     */
2185
    public function testCreateContentRequiredField(
2186
        $mainLanguageCode,
2187
        $structFields,
2188
        $identifier,
2189
        $languageCode
2190
    ) {
2191
        $fieldDefinitions = [
2192
            new FieldDefinition(
2193
                [
2194
                    'id' => 'fieldDefinitionId',
2195
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2196
                    'isTranslatable' => true,
2197
                    'identifier' => 'identifier',
2198
                    'isRequired' => true,
2199
                    'defaultValue' => 'defaultValue',
2200
                ]
2201
            ),
2202
        ];
2203
        $contentCreateStruct = $this->assertForTestCreateContentRequiredField(
2204
            $mainLanguageCode,
2205
            $structFields,
2206
            $fieldDefinitions
2207
        );
2208
2209
        $mockedService = $this->getPartlyMockedContentService();
2210
2211
        try {
2212
            $mockedService->createContent($contentCreateStruct, []);
2213
        } catch (ContentValidationException $e) {
2214
            $this->assertEquals(
2215
                "Value for required field definition '{$identifier}' with language '{$languageCode}' is empty",
2216
                $e->getMessage()
2217
            );
2218
2219
            throw $e;
2220
        }
2221
    }
2222
2223
    /**
2224
     * Asserts behaviour necessary for testing ContentFieldValidationException because of
2225
     * field not being valid.
2226
     *
2227
     * @param string $mainLanguageCode
2228
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2229
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
2230
     *
2231
     * @return mixed
2232
     */
2233
    protected function assertForTestCreateContentThrowsContentFieldValidationException(
2234
        $mainLanguageCode,
2235
        array $structFields,
2236
        array $fieldDefinitions
2237
    ) {
2238
        $repositoryMock = $this->getRepositoryMock();
2239
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
2240
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
2241
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
2242
        $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...
2243
        $domainMapperMock = $this->getDomainMapperMock();
2244
        $relationProcessorMock = $this->getRelationProcessorMock();
2245
        $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...
2246
        $languageCodes = $this->determineLanguageCodesForCreate($mainLanguageCode, $structFields);
2247
        $contentType = new ContentType(
2248
            [
2249
                'id' => 123,
2250
                'fieldDefinitions' => $fieldDefinitions,
2251
                'nameSchema' => '<nameSchema>',
2252
            ]
2253
        );
2254
        $contentCreateStruct = new ContentCreateStruct(
2255
            [
2256
                'fields' => $structFields,
2257
                'mainLanguageCode' => $mainLanguageCode,
2258
                'contentType' => $contentType,
2259
                'alwaysAvailable' => false,
2260
                'ownerId' => 169,
2261
                'sectionId' => 1,
2262
            ]
2263
        );
2264
2265
        $languageHandlerMock->expects($this->any())
2266
            ->method('loadByLanguageCode')
2267
            ->with($this->isType('string'))
2268
            ->will(
2269
                $this->returnCallback(
2270
                    function () {
2271
                        return new Language(['id' => 4242]);
2272
                    }
2273
                )
2274
            );
2275
2276
        $contentTypeServiceMock->expects($this->once())
2277
            ->method('loadContentType')
2278
            ->with($this->equalTo($contentType->id))
2279
            ->will($this->returnValue($contentType));
2280
2281
        $repositoryMock->expects($this->once())
2282
            ->method('getContentTypeService')
2283
            ->will($this->returnValue($contentTypeServiceMock));
2284
2285
        $that = $this;
2286
        $repositoryMock->expects($this->once())
2287
            ->method('canUser')
2288
            ->with(
2289
                $this->equalTo('content'),
2290
                $this->equalTo('create'),
2291
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
2292
                $this->equalTo([])
2293
            )->will(
2294
                $this->returnCallback(
2295
                    function () use ($that, $contentCreateStruct) {
2296
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
2297
2298
                        return true;
2299
                    }
2300
                )
2301
            );
2302
2303
        $domainMapperMock->expects($this->once())
2304
            ->method('getUniqueHash')
2305
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
2306
            ->will(
2307
                $this->returnCallback(
2308
                    function ($object) use ($that, $contentCreateStruct) {
2309
                        $that->assertEquals($contentCreateStruct, $object);
2310
2311
                        return 'hash';
2312
                    }
2313
                )
2314
            );
2315
2316
        $this->getFieldTypeRegistryMock()->expects($this->any())
2317
            ->method('getFieldType')
2318
            ->will($this->returnValue($fieldTypeMock));
2319
2320
        $relationProcessorMock
2321
            ->expects($this->any())
2322
            ->method('appendFieldRelations')
2323
            ->with(
2324
                $this->isType('array'),
2325
                $this->isType('array'),
2326
                $this->isInstanceOf('eZ\\Publish\\SPI\\FieldType\\FieldType'),
2327
                $this->isInstanceOf('eZ\\Publish\\Core\\FieldType\\Value'),
2328
                $this->anything()
2329
            );
2330
2331
        $fieldValues = $this->determineValuesForCreate(
2332
            $mainLanguageCode,
2333
            $structFields,
2334
            $fieldDefinitions,
2335
            $languageCodes
2336
        );
2337
        $allFieldErrors = [];
2338
        $validateCount = 0;
2339
        $emptyValue = self::EMPTY_FIELD_VALUE;
2340
        foreach ($contentType->getFieldDefinitions() as $fieldDefinition) {
2341
            foreach ($fieldValues[$fieldDefinition->identifier] as $languageCode => $value) {
2342
                $fieldTypeMock->expects($this->at($validateCount++))
2343
                    ->method('acceptValue')
2344
                    ->will(
2345
                        $this->returnCallback(
2346
                            function ($valueString) {
2347
                                return new ValueStub($valueString);
2348
                            }
2349
                        )
2350
                    );
2351
2352
                $fieldTypeMock->expects($this->at($validateCount++))
2353
                    ->method('isEmptyValue')
2354
                    ->will(
2355
                        $this->returnCallback(
2356
                            function (ValueStub $value) use ($emptyValue) {
2357
                                return $emptyValue === (string)$value;
2358
                            }
2359
                        )
2360
                    );
2361
2362
                if (self::EMPTY_FIELD_VALUE === (string)$value) {
2363
                    continue;
2364
                }
2365
2366
                $fieldTypeMock->expects($this->at($validateCount++))
2367
                    ->method('validate')
2368
                    ->with(
2369
                        $this->equalTo($fieldDefinition),
2370
                        $this->equalTo($value)
2371
                    )->will($this->returnArgument(1));
2372
2373
                $allFieldErrors[$fieldDefinition->id][$languageCode] = $value;
2374
            }
2375
        }
2376
2377
        return [$contentCreateStruct, $allFieldErrors];
2378
    }
2379
2380
    public function providerForTestCreateContentThrowsContentFieldValidationException()
2381
    {
2382
        return $this->providerForTestCreateContentNonRedundantFieldSetComplex();
2383
    }
2384
2385
    /**
2386
     * Test for the createContent() method.
2387
     *
2388
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2389
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2390
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2391
     * @dataProvider providerForTestCreateContentThrowsContentFieldValidationException
2392
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
2393
     * @expectedExceptionMessage Content fields did not validate
2394
     */
2395
    public function testCreateContentThrowsContentFieldValidationException($mainLanguageCode, $structFields)
2396
    {
2397
        $fieldDefinitions = $this->fixturesForTestCreateContentNonRedundantFieldSetComplex();
2398
        list($contentCreateStruct, $allFieldErrors) =
2399
            $this->assertForTestCreateContentThrowsContentFieldValidationException(
2400
                $mainLanguageCode,
2401
                $structFields,
2402
                $fieldDefinitions
2403
            );
2404
2405
        $mockedService = $this->getPartlyMockedContentService();
2406
2407
        try {
2408
            $mockedService->createContent($contentCreateStruct);
2409
        } catch (ContentFieldValidationException $e) {
2410
            $this->assertEquals($allFieldErrors, $e->getFieldErrors());
2411
            throw $e;
2412
        }
2413
    }
2414
2415
    /**
2416
     * Test for the createContent() method.
2417
     *
2418
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2419
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2420
     * @covers \eZ\Publish\Core\Repository\ContentService::buildSPILocationCreateStructs
2421
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2422
     */
2423
    public function testCreateContentWithLocations()
2424
    {
2425
        $spiFields = [
2426
            new SPIField(
2427
                [
2428
                    'fieldDefinitionId' => 'fieldDefinitionId',
2429
                    'type' => 'fieldTypeIdentifier',
2430
                    'value' => 'defaultValue',
2431
                    'languageCode' => 'eng-US',
2432
                ]
2433
            ),
2434
        ];
2435
        $fieldDefinitions = [
2436
            new FieldDefinition(
2437
                [
2438
                    'id' => 'fieldDefinitionId',
2439
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2440
                    'isTranslatable' => false,
2441
                    'identifier' => 'identifier',
2442
                    'isRequired' => false,
2443
                    'defaultValue' => 'defaultValue',
2444
                ]
2445
            ),
2446
        ];
2447
2448
        // Set up a simple case that will pass
2449
        $locationCreateStruct1 = new LocationCreateStruct(['parentLocationId' => 321]);
2450
        $locationCreateStruct2 = new LocationCreateStruct(['parentLocationId' => 654]);
2451
        $locationCreateStructs = [$locationCreateStruct1, $locationCreateStruct2];
2452
        $contentCreateStruct = $this->assertForTestCreateContentNonRedundantFieldSet(
2453
            'eng-US',
2454
            [],
2455
            $spiFields,
2456
            $fieldDefinitions,
2457
            $locationCreateStructs,
2458
            false,
2459
            // Do not execute
2460
            false
2461
        );
2462
2463
        $repositoryMock = $this->getRepositoryMock();
2464
        $mockedService = $this->getPartlyMockedContentService();
2465
        $locationServiceMock = $this->getLocationServiceMock();
2466
        /** @var \PHPUnit_Framework_MockObject_MockObject $handlerMock */
2467
        $handlerMock = $this->getPersistenceMock()->contentHandler();
2468
        $domainMapperMock = $this->getDomainMapperMock();
2469
        $spiLocationCreateStruct = new SPILocation\CreateStruct();
2470
        $parentLocation = new Location(['contentInfo' => new ContentInfo(['sectionId' => 1])]);
2471
2472
        $locationServiceMock->expects($this->at(0))
2473
            ->method('loadLocation')
2474
            ->with($this->equalTo(321))
2475
            ->will($this->returnValue($parentLocation));
2476
2477
        $locationServiceMock->expects($this->at(1))
2478
            ->method('loadLocation')
2479
            ->with($this->equalTo(654))
2480
            ->will($this->returnValue($parentLocation));
2481
2482
        $repositoryMock->expects($this->atLeastOnce())
2483
            ->method('getLocationService')
2484
            ->will($this->returnValue($locationServiceMock));
2485
2486
        $domainMapperMock->expects($this->at(1))
2487
            ->method('buildSPILocationCreateStruct')
2488
            ->with(
2489
                $this->equalTo($locationCreateStruct1),
2490
                $this->equalTo($parentLocation),
2491
                $this->equalTo(true),
2492
                $this->equalTo(null),
2493
                $this->equalTo(null)
2494
            )->will($this->returnValue($spiLocationCreateStruct));
2495
2496
        $domainMapperMock->expects($this->at(2))
2497
            ->method('buildSPILocationCreateStruct')
2498
            ->with(
2499
                $this->equalTo($locationCreateStruct2),
2500
                $this->equalTo($parentLocation),
2501
                $this->equalTo(false),
2502
                $this->equalTo(null),
2503
                $this->equalTo(null)
2504
            )->will($this->returnValue($spiLocationCreateStruct));
2505
2506
        $spiContentCreateStruct = new SPIContentCreateStruct(
2507
            [
2508
                'name' => [],
2509
                'typeId' => 123,
2510
                'sectionId' => 1,
2511
                'ownerId' => 169,
2512
                'remoteId' => 'hash',
2513
                'fields' => $spiFields,
2514
                'modified' => time(),
2515
                'initialLanguageId' => 4242,
2516
                'locations' => [$spiLocationCreateStruct, $spiLocationCreateStruct],
2517
            ]
2518
        );
2519
        $spiContentCreateStruct2 = clone $spiContentCreateStruct;
2520
        ++$spiContentCreateStruct2->modified;
2521
2522
        $spiContent = new SPIContent(
2523
            [
2524
                'versionInfo' => new SPIContent\VersionInfo(
2525
                    [
2526
                        'contentInfo' => new SPIContent\ContentInfo(['id' => 42]),
2527
                        'versionNo' => 7,
2528
                    ]
2529
                ),
2530
            ]
2531
        );
2532
2533
        $handlerMock->expects($this->once())
2534
            ->method('create')
2535
            ->with($this->logicalOr($spiContentCreateStruct, $spiContentCreateStruct2))
2536
            ->will($this->returnValue($spiContent));
2537
2538
        $domainMapperMock->expects($this->once())
2539
            ->method('buildContentDomainObject')
2540
            ->with(
2541
                $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content'),
2542
                $this->equalTo(null)
2543
            );
2544
2545
        $repositoryMock->expects($this->once())->method('commit');
2546
2547
        // Execute
2548
        $mockedService->createContent($contentCreateStruct, $locationCreateStructs);
2549
    }
2550
2551
    /**
2552
     * Test for the createContent() method.
2553
     *
2554
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2555
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2556
     * @covers \eZ\Publish\Core\Repository\ContentService::buildSPILocationCreateStructs
2557
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2558
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2559
     * @expectedExceptionMessage Multiple LocationCreateStructs with the same parent Location '321' are given
2560
     */
2561
    public function testCreateContentWithLocationsDuplicateUnderParent()
2562
    {
2563
        $fieldDefinitions = [
2564
            new FieldDefinition(
2565
                [
2566
                    'id' => 'fieldDefinitionId',
2567
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2568
                    'isTranslatable' => false,
2569
                    'identifier' => 'identifier',
2570
                    'isRequired' => false,
2571
                    'defaultValue' => 'defaultValue',
2572
                ]
2573
            ),
2574
        ];
2575
2576
        $repositoryMock = $this->getRepositoryMock();
2577
        $mockedService = $this->getPartlyMockedContentService();
2578
        $locationServiceMock = $this->getLocationServiceMock();
2579
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
2580
        $domainMapperMock = $this->getDomainMapperMock();
2581
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
2582
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
2583
        $spiLocationCreateStruct = new SPILocation\CreateStruct();
2584
        $parentLocation = new Location(['id' => 321]);
2585
        $locationCreateStruct = new LocationCreateStruct(['parentLocationId' => 321]);
2586
        $locationCreateStructs = [$locationCreateStruct, clone $locationCreateStruct];
2587
        $contentType = new ContentType(
2588
            [
2589
                'id' => 123,
2590
                'fieldDefinitions' => $fieldDefinitions,
2591
                'nameSchema' => '<nameSchema>',
2592
            ]
2593
        );
2594
        $contentCreateStruct = new ContentCreateStruct(
2595
            [
2596
                'fields' => [],
2597
                'mainLanguageCode' => 'eng-US',
2598
                'contentType' => $contentType,
2599
                'alwaysAvailable' => false,
2600
                'ownerId' => 169,
2601
                'sectionId' => 1,
2602
            ]
2603
        );
2604
2605
        $languageHandlerMock->expects($this->any())
2606
            ->method('loadByLanguageCode')
2607
            ->with($this->isType('string'))
2608
            ->will(
2609
                $this->returnCallback(
2610
                    function () {
2611
                        return new Language(['id' => 4242]);
2612
                    }
2613
                )
2614
            );
2615
2616
        $contentTypeServiceMock->expects($this->once())
2617
            ->method('loadContentType')
2618
            ->with($this->equalTo($contentType->id))
2619
            ->will($this->returnValue($contentType));
2620
2621
        $repositoryMock->expects($this->once())
2622
            ->method('getContentTypeService')
2623
            ->will($this->returnValue($contentTypeServiceMock));
2624
2625
        $that = $this;
2626
        $repositoryMock->expects($this->once())
2627
            ->method('canUser')
2628
            ->with(
2629
                $this->equalTo('content'),
2630
                $this->equalTo('create'),
2631
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'),
2632
                $this->equalTo($locationCreateStructs)
2633
            )->will(
2634
                $this->returnCallback(
2635
                    function () use ($that, $contentCreateStruct) {
2636
                        $that->assertEquals($contentCreateStruct, func_get_arg(2));
2637
2638
                        return true;
2639
                    }
2640
                )
2641
            );
2642
2643
        $domainMapperMock->expects($this->once())
2644
            ->method('getUniqueHash')
2645
            ->with($this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct'))
2646
            ->will(
2647
                $this->returnCallback(
2648
                    function ($object) use ($that, $contentCreateStruct) {
2649
                        $that->assertEquals($contentCreateStruct, $object);
2650
2651
                        return 'hash';
2652
                    }
2653
                )
2654
            );
2655
2656
        $locationServiceMock->expects($this->once())
2657
            ->method('loadLocation')
2658
            ->with($this->equalTo(321))
2659
            ->will($this->returnValue($parentLocation));
2660
2661
        $repositoryMock->expects($this->any())
2662
            ->method('getLocationService')
2663
            ->will($this->returnValue($locationServiceMock));
2664
2665
        $domainMapperMock->expects($this->any())
2666
            ->method('buildSPILocationCreateStruct')
2667
            ->with(
2668
                $this->equalTo($locationCreateStruct),
2669
                $this->equalTo($parentLocation),
2670
                $this->equalTo(true),
2671
                $this->equalTo(null),
2672
                $this->equalTo(null)
2673
            )->will($this->returnValue($spiLocationCreateStruct));
2674
2675
        $mockedService->createContent(
2676
            $contentCreateStruct,
2677
            $locationCreateStructs
2678
        );
2679
    }
2680
2681
    /**
2682
     * Test for the createContent() method.
2683
     *
2684
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2685
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2686
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
2687
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2688
     */
2689
    public function testCreateContentObjectStates()
2690
    {
2691
        $spiFields = [
2692
            new SPIField(
2693
                [
2694
                    'fieldDefinitionId' => 'fieldDefinitionId',
2695
                    'type' => 'fieldTypeIdentifier',
2696
                    'value' => 'defaultValue',
2697
                    'languageCode' => 'eng-US',
2698
                ]
2699
            ),
2700
        ];
2701
        $fieldDefinitions = [
2702
            new FieldDefinition(
2703
                [
2704
                    'id' => 'fieldDefinitionId',
2705
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2706
                    'isTranslatable' => false,
2707
                    'identifier' => 'identifier',
2708
                    'isRequired' => false,
2709
                    'defaultValue' => 'defaultValue',
2710
                ]
2711
            ),
2712
        ];
2713
        $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...
2714
            new SPIObjectStateGroup(['id' => 10]),
2715
            new SPIObjectStateGroup(['id' => 20]),
2716
        ];
2717
2718
        // Set up a simple case that will pass
2719
        $contentCreateStruct = $this->assertForTestCreateContentNonRedundantFieldSet(
2720
            'eng-US',
2721
            [],
2722
            $spiFields,
2723
            $fieldDefinitions,
2724
            [],
2725
            true,
2726
            // Do not execute
2727
            false
2728
        );
2729
        $timestamp = time();
2730
        $contentCreateStruct->modificationDate = new \DateTime("@{$timestamp}");
2731
2732
        $repositoryMock = $this->getRepositoryMock();
2733
        $mockedService = $this->getPartlyMockedContentService();
2734
        /** @var \PHPUnit_Framework_MockObject_MockObject $handlerMock */
2735
        $handlerMock = $this->getPersistenceMock()->contentHandler();
2736
        $domainMapperMock = $this->getDomainMapperMock();
2737
2738
        $this->mockGetDefaultObjectStates();
2739
        $this->mockSetDefaultObjectStates();
2740
2741
        $spiContentCreateStruct = new SPIContentCreateStruct(
2742
            [
2743
                'name' => [],
2744
                'typeId' => 123,
2745
                'sectionId' => 1,
2746
                'ownerId' => 169,
2747
                'remoteId' => 'hash',
2748
                'fields' => $spiFields,
2749
                'modified' => $timestamp,
2750
                'initialLanguageId' => 4242,
2751
                'locations' => [],
2752
            ]
2753
        );
2754
        $spiContentCreateStruct2 = clone $spiContentCreateStruct;
2755
        ++$spiContentCreateStruct2->modified;
2756
2757
        $spiContent = new SPIContent(
2758
            [
2759
                'versionInfo' => new SPIContent\VersionInfo(
2760
                    [
2761
                        'contentInfo' => new SPIContent\ContentInfo(['id' => 42]),
2762
                        'versionNo' => 7,
2763
                    ]
2764
                ),
2765
            ]
2766
        );
2767
2768
        $handlerMock->expects($this->once())
2769
            ->method('create')
2770
            ->with($this->equalTo($spiContentCreateStruct))
2771
            ->will($this->returnValue($spiContent));
2772
2773
        $domainMapperMock->expects($this->once())
2774
            ->method('buildContentDomainObject')
2775
            ->with(
2776
                $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content'),
2777
                $this->equalTo(null)
2778
            );
2779
2780
        $repositoryMock->expects($this->once())->method('commit');
2781
2782
        // Execute
2783
        $mockedService->createContent($contentCreateStruct, []);
2784
    }
2785
2786
    /**
2787
     * Test for the createContent() method.
2788
     *
2789
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForCreate
2790
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForCreate
2791
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
2792
     * @covers \eZ\Publish\Core\Repository\ContentService::createContent
2793
     * @dataProvider providerForTestCreateContentThrowsContentValidationExceptionTranslation
2794
     * @expectedException \Exception
2795
     * @expectedExceptionMessage Store failed
2796
     */
2797
    public function testCreateContentWithRollback()
2798
    {
2799
        $fieldDefinitions = [
2800
            new FieldDefinition(
2801
                [
2802
                    'id' => 'fieldDefinitionId',
2803
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
2804
                    'isTranslatable' => false,
2805
                    'identifier' => 'identifier',
2806
                    'isRequired' => false,
2807
                    'defaultValue' => 'defaultValue',
2808
                ]
2809
            ),
2810
        ];
2811
2812
        // Setup a simple case that will pass
2813
        $contentCreateStruct = $this->assertForTestCreateContentNonRedundantFieldSet(
2814
            'eng-US',
2815
            [],
2816
            [],
2817
            $fieldDefinitions,
2818
            [],
2819
            false,
2820
            // Do not execute test
2821
            false
2822
        );
2823
2824
        $repositoryMock = $this->getRepositoryMock();
2825
        $repositoryMock->expects($this->never())->method('commit');
2826
        $repositoryMock->expects($this->once())->method('rollback');
2827
2828
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
2829
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
2830
        $contentHandlerMock->expects($this->once())
2831
            ->method('create')
2832
            ->with($this->anything())
2833
            ->will($this->throwException(new \Exception('Store failed')));
2834
2835
        // Execute
2836
        $this->partlyMockedContentService->createContent($contentCreateStruct, []);
2837
    }
2838
2839
    public function providerForTestUpdateContentThrowsBadStateException()
2840
    {
2841
        return [
2842
            [VersionInfo::STATUS_PUBLISHED],
2843
            [VersionInfo::STATUS_ARCHIVED],
2844
        ];
2845
    }
2846
2847
    /**
2848
     * Test for the updateContent() method.
2849
     *
2850
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
2851
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
2852
     * @dataProvider providerForTestUpdateContentThrowsBadStateException
2853
     */
2854
    public function testUpdateContentThrowsBadStateException($status)
2855
    {
2856
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
2857
        $contentUpdateStruct = new ContentUpdateStruct();
2858
        $versionInfo = new VersionInfo(
2859
            [
2860
                'contentInfo' => new ContentInfo(['id' => 42]),
2861
                'versionNo' => 7,
2862
                'status' => $status,
2863
            ]
2864
        );
2865
        $content = new Content(
2866
            [
2867
                'versionInfo' => $versionInfo,
2868
                'internalFields' => [],
2869
            ]
2870
        );
2871
2872
        $mockedService->expects($this->once())
2873
            ->method('loadContent')
2874
            ->with(
2875
                $this->equalTo(42),
2876
                $this->equalTo(null),
2877
                $this->equalTo(7)
2878
            )->will(
2879
                $this->returnValue($content)
2880
            );
2881
2882
        $mockedService->updateContent($versionInfo, $contentUpdateStruct);
2883
    }
2884
2885
    /**
2886
     * Test for the updateContent() method.
2887
     *
2888
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
2889
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
2890
     */
2891
    public function testUpdateContentThrowsUnauthorizedException()
2892
    {
2893
        $repositoryMock = $this->getRepositoryMock();
2894
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
2895
        $contentUpdateStruct = new ContentUpdateStruct();
2896
        $versionInfo = new VersionInfo(
2897
            [
2898
                'contentInfo' => new ContentInfo(['id' => 42]),
2899
                'versionNo' => 7,
2900
                'status' => VersionInfo::STATUS_DRAFT,
2901
            ]
2902
        );
2903
        $content = new Content(
2904
            [
2905
                'versionInfo' => $versionInfo,
2906
                'internalFields' => [],
2907
            ]
2908
        );
2909
2910
        $mockedService->expects($this->once())
2911
            ->method('loadContent')
2912
            ->with(
2913
                $this->equalTo(42),
2914
                $this->equalTo(null),
2915
                $this->equalTo(7)
2916
            )->will(
2917
                $this->returnValue($content)
2918
            );
2919
2920
        $repositoryMock->expects($this->once())
2921
            ->method('canUser')
2922
            ->with(
2923
                $this->equalTo('content'),
2924
                $this->equalTo('edit'),
2925
                $this->equalTo($content)
2926
            )->will($this->returnValue(false));
2927
2928
        $mockedService->updateContent($versionInfo, $contentUpdateStruct);
2929
    }
2930
2931
    /**
2932
     * @param string $initialLanguageCode
2933
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2934
     * @param string[] $existingLanguages
2935
     *
2936
     * @return string[]
2937
     */
2938
    protected function determineLanguageCodesForUpdate($initialLanguageCode, array $structFields, $existingLanguages)
2939
    {
2940
        $languageCodes = array_fill_keys($existingLanguages, true);
2941
        if ($initialLanguageCode !== null) {
2942
            $languageCodes[$initialLanguageCode] = true;
2943
        }
2944
2945
        foreach ($structFields as $field) {
2946
            if ($field->languageCode === null || isset($languageCodes[$field->languageCode])) {
2947
                continue;
2948
            }
2949
2950
            $languageCodes[$field->languageCode] = true;
2951
        }
2952
2953
        return array_keys($languageCodes);
2954
    }
2955
2956
    /**
2957
     * @param string $initialLanguageCode
2958
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2959
     * @param string $mainLanguageCode
2960
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
2961
     *
2962
     * @return array
2963
     */
2964
    protected function mapStructFieldsForUpdate($initialLanguageCode, $structFields, $mainLanguageCode, $fieldDefinitions)
2965
    {
2966
        $initialLanguageCode = $initialLanguageCode ?: $mainLanguageCode;
2967
2968
        $mappedFieldDefinitions = [];
2969
        foreach ($fieldDefinitions as $fieldDefinition) {
2970
            $mappedFieldDefinitions[$fieldDefinition->identifier] = $fieldDefinition;
2971
        }
2972
2973
        $mappedStructFields = [];
2974
        foreach ($structFields as $structField) {
2975
            $identifier = $structField->fieldDefIdentifier;
2976
2977
            if ($structField->languageCode !== null) {
2978
                $languageCode = $structField->languageCode;
2979
            } elseif ($mappedFieldDefinitions[$identifier]->isTranslatable) {
2980
                $languageCode = $initialLanguageCode;
2981
            } else {
2982
                $languageCode = $mainLanguageCode;
2983
            }
2984
2985
            $mappedStructFields[$identifier][$languageCode] = (string)$structField->value;
2986
        }
2987
2988
        return $mappedStructFields;
2989
    }
2990
2991
    /**
2992
     * Returns full, possibly redundant array of field values, indexed by field definition
2993
     * identifier and language code.
2994
     *
2995
     * @param string $initialLanguageCode
2996
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
2997
     * @param \eZ\Publish\Core\Repository\Values\Content\Content $content
2998
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
2999
     * @param array $languageCodes
3000
     *
3001
     * @return array
3002
     */
3003
    protected function determineValuesForUpdate(
3004
        $initialLanguageCode,
3005
        array $structFields,
3006
        Content $content,
3007
        array $fieldDefinitions,
3008
        array $languageCodes
3009
    ) {
3010
        $mainLanguageCode = $content->versionInfo->contentInfo->mainLanguageCode;
3011
3012
        $mappedStructFields = $this->mapStructFieldsForUpdate(
3013
            $initialLanguageCode,
3014
            $structFields,
3015
            $mainLanguageCode,
3016
            $fieldDefinitions
3017
        );
3018
3019
        $values = [];
3020
3021
        foreach ($fieldDefinitions as $fieldDefinition) {
3022
            $identifier = $fieldDefinition->identifier;
3023
            foreach ($languageCodes as $languageCode) {
3024 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...
3025
                    if (isset($mappedStructFields[$identifier][$mainLanguageCode])) {
3026
                        $values[$identifier][$languageCode] = $mappedStructFields[$identifier][$mainLanguageCode];
3027
                    } else {
3028
                        $values[$identifier][$languageCode] = (string)$content->fields[$identifier][$mainLanguageCode];
3029
                    }
3030
                    continue;
3031
                }
3032
3033 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...
3034
                    $values[$identifier][$languageCode] = $mappedStructFields[$identifier][$languageCode];
3035
                    continue;
3036
                }
3037
3038
                if (isset($content->fields[$identifier][$languageCode])) {
3039
                    $values[$identifier][$languageCode] = (string)$content->fields[$identifier][$languageCode];
3040
                    continue;
3041
                }
3042
3043
                $values[$identifier][$languageCode] = (string)$fieldDefinition->defaultValue;
3044
            }
3045
        }
3046
3047
        return $this->stubValues($values);
3048
    }
3049
3050
    protected function stubValues(array $fieldValues)
3051
    {
3052
        foreach ($fieldValues as &$languageValues) {
3053
            foreach ($languageValues as &$value) {
3054
                $value = new ValueStub($value);
3055
            }
3056
        }
3057
3058
        return $fieldValues;
3059
    }
3060
3061
    /**
3062
     * Asserts that calling updateContent() with given API field set causes calling
3063
     * Handler::updateContent() with given SPI field set.
3064
     *
3065
     * @param string $initialLanguageCode
3066
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $structFields
3067
     * @param \eZ\Publish\SPI\Persistence\Content\Field[] $spiFields
3068
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $existingFields
3069
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinition[] $fieldDefinitions
3070
     * @param bool $execute
3071
     *
3072
     * @return mixed
3073
     */
3074
    protected function assertForTestUpdateContentNonRedundantFieldSet(
3075
        $initialLanguageCode,
3076
        array $structFields,
3077
        array $spiFields,
3078
        array $existingFields,
3079
        array $fieldDefinitions,
3080
        $execute = true
3081
    ) {
3082
        $repositoryMock = $this->getRepositoryMock();
3083
        $mockedService = $this->getPartlyMockedContentService(['loadContent', 'loadRelations']);
3084
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
3085
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
3086
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
3087
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
3088
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
3089
        $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...
3090
        $domainMapperMock = $this->getDomainMapperMock();
3091
        $relationProcessorMock = $this->getRelationProcessorMock();
3092
        $nameSchemaServiceMock = $this->getNameSchemaServiceMock();
3093
        $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...
3094
        $existingLanguageCodes = array_map(
3095
            function (Field $field) {
3096
                return $field->languageCode;
3097
            },
3098
            $existingFields
3099
        );
3100
        $languageCodes = $this->determineLanguageCodesForUpdate(
3101
            $initialLanguageCode,
3102
            $structFields,
3103
            $existingLanguageCodes
3104
        );
3105
        $versionInfo = new VersionInfo(
3106
            [
3107
                'contentInfo' => new ContentInfo(
3108
                    [
3109
                        'id' => 42,
3110
                        'contentTypeId' => 24,
3111
                        'mainLanguageCode' => 'eng-GB',
3112
                    ]
3113
                ),
3114
                'versionNo' => 7,
3115
                'languageCodes' => $existingLanguageCodes,
3116
                'status' => VersionInfo::STATUS_DRAFT,
3117
            ]
3118
        );
3119
        $content = new Content(
3120
            [
3121
                'versionInfo' => $versionInfo,
3122
                'internalFields' => $existingFields,
3123
            ]
3124
        );
3125
        $contentType = new ContentType(['fieldDefinitions' => $fieldDefinitions]);
3126
3127
        $languageHandlerMock->expects($this->any())
3128
            ->method('loadByLanguageCode')
3129
            ->with($this->isType('string'))
3130
            ->will(
3131
                $this->returnCallback(
3132
                    function () {
3133
                        return new Language(['id' => 4242]);
3134
                    }
3135
                )
3136
            );
3137
3138
        $mockedService->expects($this->once())
3139
            ->method('loadContent')
3140
            ->with(
3141
                $this->equalTo(42),
3142
                $this->equalTo(null),
3143
                $this->equalTo(7)
3144
            )->will(
3145
                $this->returnValue($content)
3146
            );
3147
3148
        $repositoryMock->expects($this->once())->method('beginTransaction');
3149
3150
        $repositoryMock->expects($this->once())
3151
            ->method('canUser')
3152
            ->with(
3153
                $this->equalTo('content'),
3154
                $this->equalTo('edit'),
3155
                $this->equalTo($content)
3156
            )->will($this->returnValue(true));
3157
3158
        $contentTypeServiceMock->expects($this->once())
3159
            ->method('loadContentType')
3160
            ->with($this->equalTo(24))
3161
            ->will($this->returnValue($contentType));
3162
3163
        $repositoryMock->expects($this->once())
3164
            ->method('getContentTypeService')
3165
            ->will($this->returnValue($contentTypeServiceMock));
3166
3167
        $repositoryMock->expects($this->once())
3168
            ->method('getCurrentUserReference')
3169
            ->will($this->returnValue(new UserReference(169)));
3170
3171
        $fieldTypeMock->expects($this->any())
3172
            ->method('acceptValue')
3173
            ->will(
3174
                $this->returnCallback(
3175
                    function ($valueString) {
3176
                        return new ValueStub($valueString);
3177
                    }
3178
                )
3179
            );
3180
3181
        $emptyValue = self::EMPTY_FIELD_VALUE;
3182
        $fieldTypeMock->expects($this->any())
3183
            ->method('toPersistenceValue')
3184
            ->will(
3185
                $this->returnCallback(
3186
                    function (ValueStub $value) {
3187
                        return (string)$value;
3188
                    }
3189
                )
3190
            );
3191
3192
        $fieldTypeMock->expects($this->any())
3193
            ->method('isEmptyValue')
3194
            ->will(
3195
                $this->returnCallback(
3196
                    function (ValueStub $value) use ($emptyValue) {
3197
                        return $emptyValue === (string)$value;
3198
                    }
3199
                )
3200
            );
3201
3202
        $fieldTypeMock->expects($this->any())
3203
            ->method('validate')
3204
            ->will($this->returnValue([]));
3205
3206
        $this->getFieldTypeRegistryMock()->expects($this->any())
3207
            ->method('getFieldType')
3208
            ->will($this->returnValue($fieldTypeMock));
3209
3210
        $relationProcessorMock
3211
            ->expects($this->exactly(count($fieldDefinitions) * count($languageCodes)))
3212
            ->method('appendFieldRelations')
3213
            ->with(
3214
                $this->isType('array'),
3215
                $this->isType('array'),
3216
                $this->isInstanceOf('eZ\\Publish\\SPI\\FieldType\\FieldType'),
3217
                $this->isInstanceOf('eZ\\Publish\\Core\\FieldType\\Value'),
3218
                $this->anything()
3219
            );
3220
3221
        $values = $this->determineValuesForUpdate(
3222
            $initialLanguageCode,
3223
            $structFields,
3224
            $content,
3225
            $fieldDefinitions,
3226
            $languageCodes
3227
        );
3228
        $nameSchemaServiceMock->expects($this->once())
3229
            ->method('resolveNameSchema')
3230
            ->with(
3231
                $this->equalTo($content),
3232
                $this->equalTo($values),
3233
                $this->equalTo($languageCodes)
3234
            )->will($this->returnValue([]));
3235
3236
        $existingRelations = ['RELATIONS!!!'];
3237
        $mockedService->expects($this->once())
3238
            ->method('loadRelations')
3239
            ->with($content->versionInfo)
3240
            ->will($this->returnValue($existingRelations));
3241
        $relationProcessorMock->expects($this->any())
3242
            ->method('processFieldRelations')
3243
            ->with(
3244
                $this->isType('array'),
3245
                $this->equalTo(42),
3246
                $this->isType('int'),
3247
                $this->equalTo($contentType),
3248
                $this->equalTo($existingRelations)
3249
            );
3250
3251
        $contentUpdateStruct = new ContentUpdateStruct(
3252
            [
3253
                'fields' => $structFields,
3254
                'initialLanguageCode' => $initialLanguageCode,
3255
            ]
3256
        );
3257
3258
        if ($execute) {
3259
            $spiContentUpdateStruct = new SPIContentUpdateStruct(
3260
                [
3261
                    'creatorId' => 169,
3262
                    'fields' => $spiFields,
3263
                    'modificationDate' => time(),
3264
                    'initialLanguageId' => 4242,
3265
                ]
3266
            );
3267
3268
            // During code coverage runs, timestamp might differ 1-3 seconds
3269
            $spiContentUpdateStructTs1 = clone $spiContentUpdateStruct;
3270
            ++$spiContentUpdateStructTs1->modificationDate;
3271
3272
            $spiContentUpdateStructTs2 = clone $spiContentUpdateStructTs1;
3273
            ++$spiContentUpdateStructTs2->modificationDate;
3274
3275
            $spiContentUpdateStructTs3 = clone $spiContentUpdateStructTs2;
3276
            ++$spiContentUpdateStructTs3->modificationDate;
3277
3278
            $spiContent = new SPIContent(
3279
                [
3280
                    'versionInfo' => new SPIContent\VersionInfo(
3281
                        [
3282
                            'contentInfo' => new SPIContent\ContentInfo(['id' => 42]),
3283
                            'versionNo' => 7,
3284
                        ]
3285
                    ),
3286
                ]
3287
            );
3288
3289
            $contentHandlerMock->expects($this->once())
3290
                ->method('updateContent')
3291
                ->with(
3292
                    42,
3293
                    7,
3294
                    $this->logicalOr($spiContentUpdateStruct, $spiContentUpdateStructTs1, $spiContentUpdateStructTs2, $spiContentUpdateStructTs3)
3295
                )
3296
                ->will($this->returnValue($spiContent));
3297
3298
            $repositoryMock->expects($this->once())->method('commit');
3299
            $domainMapperMock->expects($this->once())
3300
                ->method('buildContentDomainObject')
3301
                ->with(
3302
                    $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content'),
3303
                    $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType')
3304
                );
3305
3306
            $mockedService->updateContent($content->versionInfo, $contentUpdateStruct);
3307
        }
3308
3309
        return [$content->versionInfo, $contentUpdateStruct];
3310
    }
3311
3312
    public function providerForTestUpdateContentNonRedundantFieldSet1()
3313
    {
3314
        $spiFields = [
3315
            new SPIField(
3316
                [
3317
                    'id' => '100',
3318
                    'fieldDefinitionId' => 'fieldDefinitionId',
3319
                    'type' => 'fieldTypeIdentifier',
3320
                    'value' => 'newValue',
3321
                    'languageCode' => 'eng-GB',
3322
                    'versionNo' => 7,
3323
                ]
3324
            ),
3325
        ];
3326
3327
        return [
3328
            // With languages set
3329
            [
3330
                'eng-GB',
3331
                [
3332
                    new Field(
3333
                        [
3334
                            'fieldDefIdentifier' => 'identifier',
3335
                            'value' => 'newValue',
3336
                            'languageCode' => 'eng-GB',
3337
                        ]
3338
                    ),
3339
                ],
3340
                $spiFields,
3341
            ],
3342
            // Without languages set
3343
            [
3344
                null,
3345
                [
3346
                    new Field(
3347
                        [
3348
                            'fieldDefIdentifier' => 'identifier',
3349
                            'value' => 'newValue',
3350
                            'languageCode' => null,
3351
                        ]
3352
                    ),
3353
                ],
3354
                $spiFields,
3355
            ],
3356
            // Adding new language without fields
3357
            [
3358
                'eng-US',
3359
                [],
3360
                [],
3361
            ],
3362
        ];
3363
    }
3364
3365
    /**
3366
     * Test for the updateContent() method.
3367
     *
3368
     * Testing the simplest use case.
3369
     *
3370
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
3371
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
3372
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
3373
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSet1
3374
     */
3375 View Code Duplication
    public function testUpdateContentNonRedundantFieldSet1($initialLanguageCode, $structFields, $spiFields)
3376
    {
3377
        $existingFields = [
3378
            new Field(
3379
                [
3380
                    'id' => '100',
3381
                    'fieldDefIdentifier' => 'identifier',
3382
                    'value' => 'initialValue',
3383
                    'languageCode' => 'eng-GB',
3384
                ]
3385
            ),
3386
        ];
3387
3388
        $fieldDefinitions = [
3389
            new FieldDefinition(
3390
                [
3391
                    'id' => 'fieldDefinitionId',
3392
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
3393
                    'isTranslatable' => false,
3394
                    'identifier' => 'identifier',
3395
                    'isRequired' => false,
3396
                    'defaultValue' => 'defaultValue',
3397
                ]
3398
            ),
3399
        ];
3400
3401
        $this->assertForTestUpdateContentNonRedundantFieldSet(
3402
            $initialLanguageCode,
3403
            $structFields,
3404
            $spiFields,
3405
            $existingFields,
3406
            $fieldDefinitions
3407
        );
3408
    }
3409
3410
    public function providerForTestUpdateContentNonRedundantFieldSet2()
3411
    {
3412
        $spiFields0 = [
3413
            new SPIField(
3414
                [
3415
                    'id' => '100',
3416
                    'fieldDefinitionId' => 'fieldDefinitionId',
3417
                    'type' => 'fieldTypeIdentifier',
3418
                    'value' => 'newValue',
3419
                    'languageCode' => 'eng-GB',
3420
                    'versionNo' => 7,
3421
                ]
3422
            ),
3423
        ];
3424
        $spiFields1 = [
3425
            new SPIField(
3426
                [
3427
                    'id' => null,
3428
                    'fieldDefinitionId' => 'fieldDefinitionId',
3429
                    'type' => 'fieldTypeIdentifier',
3430
                    'value' => 'newValue',
3431
                    'languageCode' => 'eng-US',
3432
                    'versionNo' => 7,
3433
                ]
3434
            ),
3435
        ];
3436
        $spiFields2 = [
3437
            new SPIField(
3438
                [
3439
                    'id' => 100,
3440
                    'fieldDefinitionId' => 'fieldDefinitionId',
3441
                    'type' => 'fieldTypeIdentifier',
3442
                    'value' => 'newValue2',
3443
                    'languageCode' => 'eng-GB',
3444
                    'versionNo' => 7,
3445
                ]
3446
            ),
3447
            new SPIField(
3448
                [
3449
                    'id' => null,
3450
                    'fieldDefinitionId' => 'fieldDefinitionId',
3451
                    'type' => 'fieldTypeIdentifier',
3452
                    'value' => 'newValue1',
3453
                    'languageCode' => 'eng-US',
3454
                    'versionNo' => 7,
3455
                ]
3456
            ),
3457
        ];
3458
3459
        return [
3460
            // 0. With languages set
3461
            [
3462
                'eng-GB',
3463
                [
3464
                    new Field(
3465
                        [
3466
                            'fieldDefIdentifier' => 'identifier',
3467
                            'value' => 'newValue',
3468
                            'languageCode' => 'eng-GB',
3469
                        ]
3470
                    ),
3471
                ],
3472
                $spiFields0,
3473
            ],
3474
            // 1. Without languages set
3475
            [
3476
                null,
3477
                [
3478
                    new Field(
3479
                        [
3480
                            'fieldDefIdentifier' => 'identifier',
3481
                            'value' => 'newValue',
3482
                            'languageCode' => null,
3483
                        ]
3484
                    ),
3485
                ],
3486
                $spiFields0,
3487
            ],
3488
            // 2. New language with language set
3489
            [
3490
                'eng-GB',
3491
                [
3492
                    new Field(
3493
                        [
3494
                            'fieldDefIdentifier' => 'identifier',
3495
                            'value' => 'newValue',
3496
                            'languageCode' => 'eng-US',
3497
                        ]
3498
                    ),
3499
                ],
3500
                $spiFields1,
3501
            ],
3502
            // 3. New language without language set
3503
            [
3504
                'eng-US',
3505
                [
3506
                    new Field(
3507
                        [
3508
                            'fieldDefIdentifier' => 'identifier',
3509
                            'value' => 'newValue',
3510
                            'languageCode' => null,
3511
                        ]
3512
                    ),
3513
                ],
3514
                $spiFields1,
3515
            ],
3516
            // 4. New language and existing language with language set
3517
            [
3518
                'eng-GB',
3519
                [
3520
                    new Field(
3521
                        [
3522
                            'fieldDefIdentifier' => 'identifier',
3523
                            'value' => 'newValue1',
3524
                            'languageCode' => 'eng-US',
3525
                        ]
3526
                    ),
3527
                    new Field(
3528
                        [
3529
                            'fieldDefIdentifier' => 'identifier',
3530
                            'value' => 'newValue2',
3531
                            'languageCode' => 'eng-GB',
3532
                        ]
3533
                    ),
3534
                ],
3535
                $spiFields2,
3536
            ],
3537
            // 5. New language and existing language without language set
3538
            [
3539
                'eng-US',
3540
                [
3541
                    new Field(
3542
                        [
3543
                            'fieldDefIdentifier' => 'identifier',
3544
                            'value' => 'newValue1',
3545
                            'languageCode' => null,
3546
                        ]
3547
                    ),
3548
                    new Field(
3549
                        [
3550
                            'fieldDefIdentifier' => 'identifier',
3551
                            'value' => 'newValue2',
3552
                            'languageCode' => 'eng-GB',
3553
                        ]
3554
                    ),
3555
                ],
3556
                $spiFields2,
3557
            ],
3558
            // 6. Adding new language without fields
3559
            [
3560
                'eng-US',
3561
                [],
3562
                [
3563
                    new SPIField(
3564
                        [
3565
                            'id' => null,
3566
                            'fieldDefinitionId' => 'fieldDefinitionId',
3567
                            'type' => 'fieldTypeIdentifier',
3568
                            'value' => 'defaultValue',
3569
                            'languageCode' => 'eng-US',
3570
                            'versionNo' => 7,
3571
                        ]
3572
                    ),
3573
                ],
3574
            ],
3575
        ];
3576
    }
3577
3578
    /**
3579
     * Test for the updateContent() method.
3580
     *
3581
     * Testing with translatable field.
3582
     *
3583
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
3584
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
3585
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
3586
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSet2
3587
     */
3588 View Code Duplication
    public function testUpdateContentNonRedundantFieldSet2($initialLanguageCode, $structFields, $spiFields)
3589
    {
3590
        $existingFields = [
3591
            new Field(
3592
                [
3593
                    'id' => '100',
3594
                    'fieldDefIdentifier' => 'identifier',
3595
                    'value' => 'initialValue',
3596
                    'languageCode' => 'eng-GB',
3597
                ]
3598
            ),
3599
        ];
3600
3601
        $fieldDefinitions = [
3602
            new FieldDefinition(
3603
                [
3604
                    'id' => 'fieldDefinitionId',
3605
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
3606
                    'isTranslatable' => true,
3607
                    'identifier' => 'identifier',
3608
                    'isRequired' => false,
3609
                    'defaultValue' => 'defaultValue',
3610
                ]
3611
            ),
3612
        ];
3613
3614
        $this->assertForTestUpdateContentNonRedundantFieldSet(
3615
            $initialLanguageCode,
3616
            $structFields,
3617
            $spiFields,
3618
            $existingFields,
3619
            $fieldDefinitions
3620
        );
3621
    }
3622
3623
    public function providerForTestUpdateContentNonRedundantFieldSet3()
3624
    {
3625
        $spiFields0 = [
3626
            new SPIField(
3627
                [
3628
                    'id' => null,
3629
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3630
                    'type' => 'fieldTypeIdentifier',
3631
                    'value' => 'newValue1',
3632
                    'languageCode' => 'eng-US',
3633
                    'versionNo' => 7,
3634
                ]
3635
            ),
3636
        ];
3637
        $spiFields1 = [
3638
            new SPIField(
3639
                [
3640
                    'id' => 100,
3641
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3642
                    'type' => 'fieldTypeIdentifier',
3643
                    'value' => 'newValue2',
3644
                    'languageCode' => 'eng-GB',
3645
                    'versionNo' => 7,
3646
                ]
3647
            ),
3648
            new SPIField(
3649
                [
3650
                    'id' => null,
3651
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3652
                    'type' => 'fieldTypeIdentifier',
3653
                    'value' => 'newValue1',
3654
                    'languageCode' => 'eng-US',
3655
                    'versionNo' => 7,
3656
                ]
3657
            ),
3658
        ];
3659
        $spiFields2 = [
3660
            new SPIField(
3661
                [
3662
                    'id' => 100,
3663
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3664
                    'type' => 'fieldTypeIdentifier',
3665
                    'value' => 'newValue2',
3666
                    'languageCode' => 'eng-GB',
3667
                    'versionNo' => 7,
3668
                ]
3669
            ),
3670
            new SPIField(
3671
                [
3672
                    'id' => null,
3673
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3674
                    'type' => 'fieldTypeIdentifier',
3675
                    'value' => 'newValue1',
3676
                    'languageCode' => 'eng-US',
3677
                    'versionNo' => 7,
3678
                ]
3679
            ),
3680
            new SPIField(
3681
                [
3682
                    'id' => 101,
3683
                    'fieldDefinitionId' => 'fieldDefinitionId2',
3684
                    'type' => 'fieldTypeIdentifier',
3685
                    'value' => 'newValue3',
3686
                    'languageCode' => 'eng-GB',
3687
                    'versionNo' => 7,
3688
                ]
3689
            ),
3690
        ];
3691
        $spiFields3 = [
3692
            new SPIField(
3693
                [
3694
                    'id' => null,
3695
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3696
                    'type' => 'fieldTypeIdentifier',
3697
                    'value' => 'defaultValue1',
3698
                    'languageCode' => 'eng-US',
3699
                    'versionNo' => 7,
3700
                ]
3701
            ),
3702
        ];
3703
3704
        return [
3705
            // 0. ew language with language set
3706
            [
3707
                'eng-US',
3708
                [
3709
                    new Field(
3710
                        [
3711
                            'fieldDefIdentifier' => 'identifier1',
3712
                            'value' => 'newValue1',
3713
                            'languageCode' => 'eng-US',
3714
                        ]
3715
                    ),
3716
                ],
3717
                $spiFields0,
3718
            ],
3719
            // 1. New language without language set
3720
            [
3721
                'eng-US',
3722
                [
3723
                    new Field(
3724
                        [
3725
                            'fieldDefIdentifier' => 'identifier1',
3726
                            'value' => 'newValue1',
3727
                            'languageCode' => null,
3728
                        ]
3729
                    ),
3730
                ],
3731
                $spiFields0,
3732
            ],
3733
            // 2. New language and existing language with language set
3734
            [
3735
                'eng-US',
3736
                [
3737
                    new Field(
3738
                        [
3739
                            'fieldDefIdentifier' => 'identifier1',
3740
                            'value' => 'newValue1',
3741
                            'languageCode' => 'eng-US',
3742
                        ]
3743
                    ),
3744
                    new Field(
3745
                        [
3746
                            'fieldDefIdentifier' => 'identifier1',
3747
                            'value' => 'newValue2',
3748
                            'languageCode' => 'eng-GB',
3749
                        ]
3750
                    ),
3751
                ],
3752
                $spiFields1,
3753
            ],
3754
            // 3. New language and existing language without language set
3755
            [
3756
                'eng-US',
3757
                [
3758
                    new Field(
3759
                        [
3760
                            'fieldDefIdentifier' => 'identifier1',
3761
                            'value' => 'newValue1',
3762
                            'languageCode' => null,
3763
                        ]
3764
                    ),
3765
                    new Field(
3766
                        [
3767
                            'fieldDefIdentifier' => 'identifier1',
3768
                            'value' => 'newValue2',
3769
                            'languageCode' => 'eng-GB',
3770
                        ]
3771
                    ),
3772
                ],
3773
                $spiFields1,
3774
            ],
3775
            // 4. New language and existing language with untranslatable field, with language set
3776
            [
3777
                'eng-US',
3778
                [
3779
                    new Field(
3780
                        [
3781
                            'fieldDefIdentifier' => 'identifier1',
3782
                            'value' => 'newValue1',
3783
                            'languageCode' => 'eng-US',
3784
                        ]
3785
                    ),
3786
                    new Field(
3787
                        [
3788
                            'fieldDefIdentifier' => 'identifier1',
3789
                            'value' => 'newValue2',
3790
                            'languageCode' => 'eng-GB',
3791
                        ]
3792
                    ),
3793
                    new Field(
3794
                        [
3795
                            'fieldDefIdentifier' => 'identifier2',
3796
                            'value' => 'newValue3',
3797
                            'languageCode' => 'eng-GB',
3798
                        ]
3799
                    ),
3800
                ],
3801
                $spiFields2,
3802
            ],
3803
            // 5. New language and existing language with untranslatable field, without language set
3804
            [
3805
                'eng-US',
3806
                [
3807
                    new Field(
3808
                        [
3809
                            'fieldDefIdentifier' => 'identifier1',
3810
                            'value' => 'newValue1',
3811
                            'languageCode' => null,
3812
                        ]
3813
                    ),
3814
                    new Field(
3815
                        [
3816
                            'fieldDefIdentifier' => 'identifier1',
3817
                            'value' => 'newValue2',
3818
                            'languageCode' => 'eng-GB',
3819
                        ]
3820
                    ),
3821
                    new Field(
3822
                        [
3823
                            'fieldDefIdentifier' => 'identifier2',
3824
                            'value' => 'newValue3',
3825
                            'languageCode' => null,
3826
                        ]
3827
                    ),
3828
                ],
3829
                $spiFields2,
3830
            ],
3831
            // 6. Adding new language without fields
3832
            [
3833
                'eng-US',
3834
                [],
3835
                $spiFields3,
3836
            ],
3837
        ];
3838
    }
3839
3840
    /**
3841
     * Test for the updateContent() method.
3842
     *
3843
     * Testing with new language and untranslatable field.
3844
     *
3845
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
3846
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
3847
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
3848
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSet3
3849
     */
3850
    public function testUpdateContentNonRedundantFieldSet3($initialLanguageCode, $structFields, $spiFields)
3851
    {
3852
        $existingFields = [
3853
            new Field(
3854
                [
3855
                    'id' => '100',
3856
                    'fieldDefIdentifier' => 'identifier1',
3857
                    'value' => 'initialValue1',
3858
                    'languageCode' => 'eng-GB',
3859
                ]
3860
            ),
3861
            new Field(
3862
                [
3863
                    'id' => '101',
3864
                    'fieldDefIdentifier' => 'identifier2',
3865
                    'value' => 'initialValue2',
3866
                    'languageCode' => 'eng-GB',
3867
                ]
3868
            ),
3869
        ];
3870
3871
        $fieldDefinitions = [
3872
            new FieldDefinition(
3873
                [
3874
                    'id' => 'fieldDefinitionId1',
3875
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
3876
                    'isTranslatable' => true,
3877
                    'identifier' => 'identifier1',
3878
                    'isRequired' => false,
3879
                    'defaultValue' => 'defaultValue1',
3880
                ]
3881
            ),
3882
            new FieldDefinition(
3883
                [
3884
                    'id' => 'fieldDefinitionId2',
3885
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
3886
                    'isTranslatable' => false,
3887
                    'identifier' => 'identifier2',
3888
                    'isRequired' => false,
3889
                    'defaultValue' => 'defaultValue2',
3890
                ]
3891
            ),
3892
        ];
3893
3894
        $this->assertForTestUpdateContentNonRedundantFieldSet(
3895
            $initialLanguageCode,
3896
            $structFields,
3897
            $spiFields,
3898
            $existingFields,
3899
            $fieldDefinitions
3900
        );
3901
    }
3902
3903
    public function providerForTestUpdateContentNonRedundantFieldSet4()
3904
    {
3905
        $spiFields0 = [
3906
            new SPIField(
3907
                [
3908
                    'id' => null,
3909
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3910
                    'type' => 'fieldTypeIdentifier',
3911
                    'value' => 'newValue1',
3912
                    'languageCode' => 'eng-US',
3913
                    'versionNo' => 7,
3914
                ]
3915
            ),
3916
        ];
3917
        $spiFields1 = [
3918
            new SPIField(
3919
                [
3920
                    'id' => 100,
3921
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3922
                    'type' => 'fieldTypeIdentifier',
3923
                    'value' => self::EMPTY_FIELD_VALUE,
3924
                    'languageCode' => 'eng-GB',
3925
                    'versionNo' => 7,
3926
                ]
3927
            ),
3928
            new SPIField(
3929
                [
3930
                    'id' => null,
3931
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3932
                    'type' => 'fieldTypeIdentifier',
3933
                    'value' => 'newValue1',
3934
                    'languageCode' => 'eng-US',
3935
                    'versionNo' => 7,
3936
                ]
3937
            ),
3938
        ];
3939
        $spiFields2 = [
3940
            new SPIField(
3941
                [
3942
                    'id' => 100,
3943
                    'fieldDefinitionId' => 'fieldDefinitionId1',
3944
                    'type' => 'fieldTypeIdentifier',
3945
                    'value' => self::EMPTY_FIELD_VALUE,
3946
                    'languageCode' => 'eng-GB',
3947
                    'versionNo' => 7,
3948
                ]
3949
            ),
3950
        ];
3951
3952
        return [
3953
            // 0. New translation with empty field by default
3954
            [
3955
                'eng-US',
3956
                [
3957
                    new Field(
3958
                        [
3959
                            'fieldDefIdentifier' => 'identifier1',
3960
                            'value' => 'newValue1',
3961
                            'languageCode' => 'eng-US',
3962
                        ]
3963
                    ),
3964
                ],
3965
                $spiFields0,
3966
            ],
3967
            // 1. New translation with empty field by default, without language set
3968
            [
3969
                'eng-US',
3970
                [
3971
                    new Field(
3972
                        [
3973
                            'fieldDefIdentifier' => 'identifier1',
3974
                            'value' => 'newValue1',
3975
                            'languageCode' => null,
3976
                        ]
3977
                    ),
3978
                ],
3979
                $spiFields0,
3980
            ],
3981
            // 2. New translation with empty field given
3982
            [
3983
                'eng-US',
3984
                [
3985
                    new Field(
3986
                        [
3987
                            'fieldDefIdentifier' => 'identifier1',
3988
                            'value' => 'newValue1',
3989
                            'languageCode' => 'eng-US',
3990
                        ]
3991
                    ),
3992
                    new Field(
3993
                        [
3994
                            'fieldDefIdentifier' => 'identifier2',
3995
                            'value' => self::EMPTY_FIELD_VALUE,
3996
                            'languageCode' => 'eng-US',
3997
                        ]
3998
                    ),
3999
                ],
4000
                $spiFields0,
4001
            ],
4002
            // 3. New translation with empty field given, without language set
4003
            [
4004
                'eng-US',
4005
                [
4006
                    new Field(
4007
                        [
4008
                            'fieldDefIdentifier' => 'identifier1',
4009
                            'value' => 'newValue1',
4010
                            'languageCode' => null,
4011
                        ]
4012
                    ),
4013
                    new Field(
4014
                        [
4015
                            'fieldDefIdentifier' => 'identifier2',
4016
                            'value' => self::EMPTY_FIELD_VALUE,
4017
                            'languageCode' => null,
4018
                        ]
4019
                    ),
4020
                ],
4021
                $spiFields0,
4022
            ],
4023
            // 4. Updating existing language with empty value
4024
            [
4025
                'eng-US',
4026
                [
4027
                    new Field(
4028
                        [
4029
                            'fieldDefIdentifier' => 'identifier1',
4030
                            'value' => 'newValue1',
4031
                            'languageCode' => 'eng-US',
4032
                        ]
4033
                    ),
4034
                    new Field(
4035
                        [
4036
                            'fieldDefIdentifier' => 'identifier1',
4037
                            'value' => self::EMPTY_FIELD_VALUE,
4038
                            'languageCode' => 'eng-GB',
4039
                        ]
4040
                    ),
4041
                ],
4042
                $spiFields1,
4043
            ],
4044
            // 5. Updating existing language with empty value, without language set
4045
            [
4046
                'eng-US',
4047
                [
4048
                    new Field(
4049
                        [
4050
                            'fieldDefIdentifier' => 'identifier1',
4051
                            'value' => 'newValue1',
4052
                            'languageCode' => null,
4053
                        ]
4054
                    ),
4055
                    new Field(
4056
                        [
4057
                            'fieldDefIdentifier' => 'identifier1',
4058
                            'value' => self::EMPTY_FIELD_VALUE,
4059
                            'languageCode' => 'eng-GB',
4060
                        ]
4061
                    ),
4062
                ],
4063
                $spiFields1,
4064
            ],
4065
            // 6. Updating existing language with empty value and adding new language with empty value
4066
            [
4067
                'eng-US',
4068
                [
4069
                    new Field(
4070
                        [
4071
                            'fieldDefIdentifier' => 'identifier1',
4072
                            'value' => self::EMPTY_FIELD_VALUE,
4073
                            'languageCode' => 'eng-US',
4074
                        ]
4075
                    ),
4076
                    new Field(
4077
                        [
4078
                            'fieldDefIdentifier' => 'identifier1',
4079
                            'value' => self::EMPTY_FIELD_VALUE,
4080
                            'languageCode' => 'eng-GB',
4081
                        ]
4082
                    ),
4083
                ],
4084
                $spiFields2,
4085
            ],
4086
            // 7. Updating existing language with empty value and adding new language with empty value,
4087
            // without language set
4088
            [
4089
                'eng-US',
4090
                [
4091
                    new Field(
4092
                        [
4093
                            'fieldDefIdentifier' => 'identifier1',
4094
                            'value' => self::EMPTY_FIELD_VALUE,
4095
                            'languageCode' => null,
4096
                        ]
4097
                    ),
4098
                    new Field(
4099
                        [
4100
                            'fieldDefIdentifier' => 'identifier1',
4101
                            'value' => self::EMPTY_FIELD_VALUE,
4102
                            'languageCode' => 'eng-GB',
4103
                        ]
4104
                    ),
4105
                ],
4106
                $spiFields2,
4107
            ],
4108
            // 8. Adding new language with no fields given
4109
            [
4110
                'eng-US',
4111
                [],
4112
                [],
4113
            ],
4114
            // 9. Adding new language with fields
4115
            [
4116
                'eng-US',
4117
                [
4118
                    new Field(
4119
                        [
4120
                            'fieldDefIdentifier' => 'identifier1',
4121
                            'value' => self::EMPTY_FIELD_VALUE,
4122
                            'languageCode' => 'eng-US',
4123
                        ]
4124
                    ),
4125
                ],
4126
                [],
4127
            ],
4128
            // 10. Adding new language with fields, without language set
4129
            [
4130
                'eng-US',
4131
                [
4132
                    new Field(
4133
                        [
4134
                            'fieldDefIdentifier' => 'identifier1',
4135
                            'value' => self::EMPTY_FIELD_VALUE,
4136
                            'languageCode' => null,
4137
                        ]
4138
                    ),
4139
                ],
4140
                [],
4141
            ],
4142
        ];
4143
    }
4144
4145
    /**
4146
     * Test for the updateContent() method.
4147
     *
4148
     * Testing with empty values.
4149
     *
4150
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4151
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4152
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4153
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSet4
4154
     */
4155
    public function testUpdateContentNonRedundantFieldSet4($initialLanguageCode, $structFields, $spiFields)
4156
    {
4157
        $existingFields = [
4158
            new Field(
4159
                [
4160
                    'id' => '100',
4161
                    'fieldDefIdentifier' => 'identifier1',
4162
                    'value' => 'initialValue1',
4163
                    'languageCode' => 'eng-GB',
4164
                ]
4165
            ),
4166
            new Field(
4167
                [
4168
                    'id' => '101',
4169
                    'fieldDefIdentifier' => 'identifier2',
4170
                    'value' => 'initialValue2',
4171
                    'languageCode' => 'eng-GB',
4172
                ]
4173
            ),
4174
        ];
4175
4176
        $fieldDefinitions = [
4177
            new FieldDefinition(
4178
                [
4179
                    'id' => 'fieldDefinitionId1',
4180
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4181
                    'isTranslatable' => true,
4182
                    'identifier' => 'identifier1',
4183
                    'isRequired' => false,
4184
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4185
                ]
4186
            ),
4187
            new FieldDefinition(
4188
                [
4189
                    'id' => 'fieldDefinitionId2',
4190
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4191
                    'isTranslatable' => true,
4192
                    'identifier' => 'identifier2',
4193
                    'isRequired' => false,
4194
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4195
                ]
4196
            ),
4197
        ];
4198
4199
        $this->assertForTestUpdateContentNonRedundantFieldSet(
4200
            $initialLanguageCode,
4201
            $structFields,
4202
            $spiFields,
4203
            $existingFields,
4204
            $fieldDefinitions
4205
        );
4206
    }
4207
4208
    /**
4209
     * @todo add first field empty
4210
     *
4211
     * @return array
4212
     */
4213
    public function providerForTestUpdateContentNonRedundantFieldSetComplex()
4214
    {
4215
        $spiFields0 = [
4216
            new SPIField(
4217
                [
4218
                    'id' => 100,
4219
                    'fieldDefinitionId' => 'fieldDefinitionId1',
4220
                    'type' => 'fieldTypeIdentifier',
4221
                    'value' => 'newValue1-eng-GB',
4222
                    'languageCode' => 'eng-GB',
4223
                    'versionNo' => 7,
4224
                ]
4225
            ),
4226
            new SPIField(
4227
                [
4228
                    'id' => null,
4229
                    'fieldDefinitionId' => 'fieldDefinitionId4',
4230
                    'type' => 'fieldTypeIdentifier',
4231
                    'value' => 'newValue4',
4232
                    'languageCode' => 'eng-US',
4233
                    'versionNo' => 7,
4234
                ]
4235
            ),
4236
        ];
4237
        $spiFields1 = [
4238
            new SPIField(
4239
                [
4240
                    'id' => 100,
4241
                    'fieldDefinitionId' => 'fieldDefinitionId1',
4242
                    'type' => 'fieldTypeIdentifier',
4243
                    'value' => 'newValue1-eng-GB',
4244
                    'languageCode' => 'eng-GB',
4245
                    'versionNo' => 7,
4246
                ]
4247
            ),
4248
            new SPIField(
4249
                [
4250
                    'id' => null,
4251
                    'fieldDefinitionId' => 'fieldDefinitionId2',
4252
                    'type' => 'fieldTypeIdentifier',
4253
                    'value' => 'newValue2',
4254
                    'languageCode' => 'eng-US',
4255
                    'versionNo' => 7,
4256
                ]
4257
            ),
4258
            new SPIField(
4259
                [
4260
                    'id' => null,
4261
                    'fieldDefinitionId' => 'fieldDefinitionId4',
4262
                    'type' => 'fieldTypeIdentifier',
4263
                    'value' => 'defaultValue4',
4264
                    'languageCode' => 'eng-US',
4265
                    'versionNo' => 7,
4266
                ]
4267
            ),
4268
        ];
4269
        $spiFields2 = [
4270
            new SPIField(
4271
                [
4272
                    'id' => 100,
4273
                    'fieldDefinitionId' => 'fieldDefinitionId1',
4274
                    'type' => 'fieldTypeIdentifier',
4275
                    'value' => 'newValue1-eng-GB',
4276
                    'languageCode' => 'eng-GB',
4277
                    'versionNo' => 7,
4278
                ]
4279
            ),
4280
            new SPIField(
4281
                [
4282
                    'id' => null,
4283
                    'fieldDefinitionId' => 'fieldDefinitionId2',
4284
                    'type' => 'fieldTypeIdentifier',
4285
                    'value' => 'newValue2',
4286
                    'languageCode' => 'eng-US',
4287
                    'versionNo' => 7,
4288
                ]
4289
            ),
4290
            new SPIField(
4291
                [
4292
                    'id' => null,
4293
                    'fieldDefinitionId' => 'fieldDefinitionId4',
4294
                    'type' => 'fieldTypeIdentifier',
4295
                    'value' => 'defaultValue4',
4296
                    'languageCode' => 'ger-DE',
4297
                    'versionNo' => 7,
4298
                ]
4299
            ),
4300
            new SPIField(
4301
                [
4302
                    'id' => null,
4303
                    'fieldDefinitionId' => 'fieldDefinitionId4',
4304
                    'type' => 'fieldTypeIdentifier',
4305
                    'value' => 'defaultValue4',
4306
                    'languageCode' => 'eng-US',
4307
                    'versionNo' => 7,
4308
                ]
4309
            ),
4310
        ];
4311
4312
        return [
4313
            // 0. Add new language and update existing
4314
            [
4315
                'eng-US',
4316
                [
4317
                    new Field(
4318
                        [
4319
                            'fieldDefIdentifier' => 'identifier4',
4320
                            'value' => 'newValue4',
4321
                            'languageCode' => 'eng-US',
4322
                        ]
4323
                    ),
4324
                    new Field(
4325
                        [
4326
                            'fieldDefIdentifier' => 'identifier1',
4327
                            'value' => 'newValue1-eng-GB',
4328
                            'languageCode' => 'eng-GB',
4329
                        ]
4330
                    ),
4331
                ],
4332
                $spiFields0,
4333
            ],
4334
            // 1. Add new language and update existing, without language set
4335
            [
4336
                'eng-US',
4337
                [
4338
                    new Field(
4339
                        [
4340
                            'fieldDefIdentifier' => 'identifier4',
4341
                            'value' => 'newValue4',
4342
                            'languageCode' => null,
4343
                        ]
4344
                    ),
4345
                    new Field(
4346
                        [
4347
                            'fieldDefIdentifier' => 'identifier1',
4348
                            'value' => 'newValue1-eng-GB',
4349
                            'languageCode' => 'eng-GB',
4350
                        ]
4351
                    ),
4352
                ],
4353
                $spiFields0,
4354
            ],
4355
            // 2. Add new language and update existing variant
4356
            [
4357
                'eng-US',
4358
                [
4359
                    new Field(
4360
                        [
4361
                            'fieldDefIdentifier' => 'identifier2',
4362
                            'value' => 'newValue2',
4363
                            'languageCode' => 'eng-US',
4364
                        ]
4365
                    ),
4366
                    new Field(
4367
                        [
4368
                            'fieldDefIdentifier' => 'identifier1',
4369
                            'value' => 'newValue1-eng-GB',
4370
                            'languageCode' => 'eng-GB',
4371
                        ]
4372
                    ),
4373
                ],
4374
                $spiFields1,
4375
            ],
4376
            // 3. Add new language and update existing variant, without language set
4377
            [
4378
                'eng-US',
4379
                [
4380
                    new Field(
4381
                        [
4382
                            'fieldDefIdentifier' => 'identifier2',
4383
                            'value' => 'newValue2',
4384
                            'languageCode' => null,
4385
                        ]
4386
                    ),
4387
                    new Field(
4388
                        [
4389
                            'fieldDefIdentifier' => 'identifier1',
4390
                            'value' => 'newValue1-eng-GB',
4391
                            'languageCode' => 'eng-GB',
4392
                        ]
4393
                    ),
4394
                ],
4395
                $spiFields1,
4396
            ],
4397
            // 4. Update with multiple languages
4398
            [
4399
                'ger-DE',
4400
                [
4401
                    new Field(
4402
                        [
4403
                            'fieldDefIdentifier' => 'identifier2',
4404
                            'value' => 'newValue2',
4405
                            'languageCode' => 'eng-US',
4406
                        ]
4407
                    ),
4408
                    new Field(
4409
                        [
4410
                            'fieldDefIdentifier' => 'identifier1',
4411
                            'value' => 'newValue1-eng-GB',
4412
                            'languageCode' => 'eng-GB',
4413
                        ]
4414
                    ),
4415
                ],
4416
                $spiFields2,
4417
            ],
4418
            // 5. Update with multiple languages without language set
4419
            [
4420
                'ger-DE',
4421
                [
4422
                    new Field(
4423
                        [
4424
                            'fieldDefIdentifier' => 'identifier2',
4425
                            'value' => 'newValue2',
4426
                            'languageCode' => 'eng-US',
4427
                        ]
4428
                    ),
4429
                    new Field(
4430
                        [
4431
                            'fieldDefIdentifier' => 'identifier1',
4432
                            'value' => 'newValue1-eng-GB',
4433
                            'languageCode' => null,
4434
                        ]
4435
                    ),
4436
                ],
4437
                $spiFields2,
4438
            ],
4439
        ];
4440
    }
4441
4442
    protected function fixturesForTestUpdateContentNonRedundantFieldSetComplex()
4443
    {
4444
        $existingFields = [
4445
            new Field(
4446
                [
4447
                    'id' => '100',
4448
                    'fieldDefIdentifier' => 'identifier1',
4449
                    'value' => 'initialValue1',
4450
                    'languageCode' => 'eng-GB',
4451
                ]
4452
            ),
4453
            new Field(
4454
                [
4455
                    'id' => '101',
4456
                    'fieldDefIdentifier' => 'identifier2',
4457
                    'value' => 'initialValue2',
4458
                    'languageCode' => 'eng-GB',
4459
                ]
4460
            ),
4461
            new Field(
4462
                [
4463
                    'id' => '102',
4464
                    'fieldDefIdentifier' => 'identifier3',
4465
                    'value' => 'initialValue3',
4466
                    'languageCode' => 'eng-GB',
4467
                ]
4468
            ),
4469
            new Field(
4470
                [
4471
                    'id' => '103',
4472
                    'fieldDefIdentifier' => 'identifier4',
4473
                    'value' => 'initialValue4',
4474
                    'languageCode' => 'eng-GB',
4475
                ]
4476
            ),
4477
        ];
4478
4479
        $fieldDefinitions = [
4480
            new FieldDefinition(
4481
                [
4482
                    'id' => 'fieldDefinitionId1',
4483
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4484
                    'isTranslatable' => false,
4485
                    'identifier' => 'identifier1',
4486
                    'isRequired' => false,
4487
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4488
                ]
4489
            ),
4490
            new FieldDefinition(
4491
                [
4492
                    'id' => 'fieldDefinitionId2',
4493
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4494
                    'isTranslatable' => true,
4495
                    'identifier' => 'identifier2',
4496
                    'isRequired' => false,
4497
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4498
                ]
4499
            ),
4500
            new FieldDefinition(
4501
                [
4502
                    'id' => 'fieldDefinitionId3',
4503
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4504
                    'isTranslatable' => false,
4505
                    'identifier' => 'identifier3',
4506
                    'isRequired' => false,
4507
                    'defaultValue' => 'defaultValue3',
4508
                ]
4509
            ),
4510
            new FieldDefinition(
4511
                [
4512
                    'id' => 'fieldDefinitionId4',
4513
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4514
                    'isTranslatable' => true,
4515
                    'identifier' => 'identifier4',
4516
                    'isRequired' => false,
4517
                    'defaultValue' => 'defaultValue4',
4518
                ]
4519
            ),
4520
        ];
4521
4522
        return [$existingFields, $fieldDefinitions];
4523
    }
4524
4525
    /**
4526
     * Test for the updateContent() method.
4527
     *
4528
     * Testing more complex cases.
4529
     *
4530
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4531
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4532
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4533
     * @dataProvider providerForTestUpdateContentNonRedundantFieldSetComplex
4534
     */
4535
    public function testUpdateContentNonRedundantFieldSetComplex($initialLanguageCode, $structFields, $spiFields)
4536
    {
4537
        list($existingFields, $fieldDefinitions) = $this->fixturesForTestUpdateContentNonRedundantFieldSetComplex();
4538
4539
        $this->assertForTestUpdateContentNonRedundantFieldSet(
4540
            $initialLanguageCode,
4541
            $structFields,
4542
            $spiFields,
4543
            $existingFields,
4544
            $fieldDefinitions
4545
        );
4546
    }
4547
4548 View Code Duplication
    public function providerForTestUpdateContentWithInvalidLanguage()
4549
    {
4550
        return [
4551
            [
4552
                'eng-GB',
4553
                [
4554
                    new Field(
4555
                        [
4556
                            'fieldDefIdentifier' => 'identifier',
4557
                            'value' => 'newValue',
4558
                            'languageCode' => 'Klingon',
4559
                        ]
4560
                    ),
4561
                ],
4562
            ],
4563
            [
4564
                'Klingon',
4565
                [
4566
                    new Field(
4567
                        [
4568
                            'fieldDefIdentifier' => 'identifier',
4569
                            'value' => 'newValue',
4570
                            'languageCode' => 'eng-GB',
4571
                        ]
4572
                    ),
4573
                ],
4574
            ],
4575
        ];
4576
    }
4577
4578
    /**
4579
     * Test for the updateContent() method.
4580
     *
4581
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4582
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4583
     * @dataProvider providerForTestUpdateContentWithInvalidLanguage
4584
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
4585
     * @expectedExceptionMessage Could not find 'Language' with identifier 'Klingon'
4586
     */
4587
    public function testUpdateContentWithInvalidLanguage($initialLanguageCode, $structFields)
4588
    {
4589
        $repositoryMock = $this->getRepositoryMock();
4590
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
4591
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
4592
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
4593
        $versionInfo = new VersionInfo(
4594
            [
4595
                'contentInfo' => new ContentInfo(
4596
                    [
4597
                        'id' => 42,
4598
                        'contentTypeId' => 24,
4599
                        'mainLanguageCode' => 'eng-GB',
4600
                    ]
4601
                ),
4602
                'versionNo' => 7,
4603
                'languageCodes' => ['eng-GB'],
4604
                'status' => VersionInfo::STATUS_DRAFT,
4605
            ]
4606
        );
4607
        $content = new Content(
4608
            [
4609
                'versionInfo' => $versionInfo,
4610
                'internalFields' => [],
4611
            ]
4612
        );
4613
4614
        $languageHandlerMock->expects($this->any())
4615
            ->method('loadByLanguageCode')
4616
            ->with($this->isType('string'))
4617
            ->will(
4618
                $this->returnCallback(
4619 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...
4620
                        if ($languageCode === 'Klingon') {
4621
                            throw new NotFoundException('Language', 'Klingon');
4622
                        }
4623
4624
                        return new Language(['id' => 4242]);
4625
                    }
4626
                )
4627
            );
4628
4629
        $mockedService->expects($this->once())
4630
            ->method('loadContent')
4631
            ->with(
4632
                $this->equalTo(42),
4633
                $this->equalTo(null),
4634
                $this->equalTo(7)
4635
            )->will(
4636
                $this->returnValue($content)
4637
            );
4638
4639
        $repositoryMock->expects($this->once())
4640
            ->method('canUser')
4641
            ->with(
4642
                $this->equalTo('content'),
4643
                $this->equalTo('edit'),
4644
                $this->equalTo($content)
4645
            )->will($this->returnValue(true));
4646
4647
        $contentUpdateStruct = new ContentUpdateStruct(
4648
            [
4649
                'fields' => $structFields,
4650
                'initialLanguageCode' => $initialLanguageCode,
4651
            ]
4652
        );
4653
4654
        $mockedService->updateContent($content->versionInfo, $contentUpdateStruct);
4655
    }
4656
4657
    protected function assertForUpdateContentContentValidationException(
4658
        $initialLanguageCode,
4659
        $structFields,
4660
        $fieldDefinitions = []
4661
    ) {
4662
        $repositoryMock = $this->getRepositoryMock();
4663
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
4664
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
4665
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
4666
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
4667
        $versionInfo = new VersionInfo(
4668
            [
4669
                'contentInfo' => new ContentInfo(
4670
                    [
4671
                        'id' => 42,
4672
                        'contentTypeId' => 24,
4673
                        'mainLanguageCode' => 'eng-GB',
4674
                    ]
4675
                ),
4676
                'versionNo' => 7,
4677
                'languageCodes' => ['eng-GB'],
4678
                'status' => VersionInfo::STATUS_DRAFT,
4679
            ]
4680
        );
4681
        $content = new Content(
4682
            [
4683
                'versionInfo' => $versionInfo,
4684
                'internalFields' => [],
4685
            ]
4686
        );
4687
        $contentType = new ContentType(['fieldDefinitions' => $fieldDefinitions]);
4688
4689
        $languageHandlerMock->expects($this->any())
4690
            ->method('loadByLanguageCode')
4691
            ->with($this->isType('string'))
4692
            ->will(
4693
                $this->returnCallback(
4694 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...
4695
                        if ($languageCode === 'Klingon') {
4696
                            throw new NotFoundException('Language', 'Klingon');
4697
                        }
4698
4699
                        return new Language(['id' => 4242]);
4700
                    }
4701
                )
4702
            );
4703
4704
        $mockedService->expects($this->once())
4705
            ->method('loadContent')
4706
            ->with(
4707
                $this->equalTo(42),
4708
                $this->equalTo(null),
4709
                $this->equalTo(7)
4710
            )->will(
4711
                $this->returnValue($content)
4712
            );
4713
4714
        $repositoryMock->expects($this->once())
4715
            ->method('canUser')
4716
            ->with(
4717
                $this->equalTo('content'),
4718
                $this->equalTo('edit'),
4719
                $this->equalTo($content)
4720
            )->will($this->returnValue(true));
4721
4722
        $contentTypeServiceMock->expects($this->once())
4723
            ->method('loadContentType')
4724
            ->with($this->equalTo(24))
4725
            ->will($this->returnValue($contentType));
4726
4727
        $repositoryMock->expects($this->once())
4728
            ->method('getContentTypeService')
4729
            ->will($this->returnValue($contentTypeServiceMock));
4730
4731
        $contentUpdateStruct = new ContentUpdateStruct(
4732
            [
4733
                'fields' => $structFields,
4734
                'initialLanguageCode' => $initialLanguageCode,
4735
            ]
4736
        );
4737
4738
        $mockedService->updateContent($content->versionInfo, $contentUpdateStruct);
4739
    }
4740
4741 View Code Duplication
    public function providerForTestUpdateContentThrowsContentValidationExceptionFieldDefinition()
4742
    {
4743
        return [
4744
            [
4745
                'eng-GB',
4746
                [
4747
                    new Field(
4748
                        [
4749
                            'fieldDefIdentifier' => 'identifier',
4750
                            'value' => 'newValue',
4751
                            'languageCode' => 'eng-GB',
4752
                        ]
4753
                    ),
4754
                ],
4755
            ],
4756
        ];
4757
    }
4758
4759
    /**
4760
     * Test for the updateContent() method.
4761
     *
4762
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4763
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4764
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4765
     * @dataProvider providerForTestUpdateContentThrowsContentValidationExceptionFieldDefinition
4766
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentValidationException
4767
     * @expectedExceptionMessage Field definition 'identifier' does not exist in given ContentType
4768
     */
4769
    public function testUpdateContentThrowsContentValidationExceptionFieldDefinition($initialLanguageCode, $structFields)
4770
    {
4771
        $this->assertForUpdateContentContentValidationException(
4772
            $initialLanguageCode,
4773
            $structFields,
4774
            []
4775
        );
4776
    }
4777
4778 View Code Duplication
    public function providerForTestUpdateContentThrowsContentValidationExceptionTranslation()
4779
    {
4780
        return [
4781
            [
4782
                'eng-US',
4783
                [
4784
                    new Field(
4785
                        [
4786
                            'fieldDefIdentifier' => 'identifier',
4787
                            'value' => 'newValue',
4788
                            'languageCode' => 'eng-US',
4789
                        ]
4790
                    ),
4791
                ],
4792
            ],
4793
        ];
4794
    }
4795
4796
    /**
4797
     * Test for the updateContent() method.
4798
     *
4799
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4800
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4801
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4802
     * @dataProvider providerForTestUpdateContentThrowsContentValidationExceptionTranslation
4803
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentValidationException
4804
     * @expectedExceptionMessage A value is set for non translatable field definition 'identifier' with language 'eng-US'
4805
     */
4806 View Code Duplication
    public function testUpdateContentThrowsContentValidationExceptionTranslation($initialLanguageCode, $structFields)
4807
    {
4808
        $fieldDefinitions = [
4809
            new FieldDefinition(
4810
                [
4811
                    'id' => 'fieldDefinitionId1',
4812
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4813
                    'isTranslatable' => false,
4814
                    'identifier' => 'identifier',
4815
                    'isRequired' => false,
4816
                    'defaultValue' => self::EMPTY_FIELD_VALUE,
4817
                ]
4818
            ),
4819
        ];
4820
4821
        $this->assertForUpdateContentContentValidationException(
4822
            $initialLanguageCode,
4823
            $structFields,
4824
            $fieldDefinitions
4825
        );
4826
    }
4827
4828
    public function assertForTestUpdateContentRequiredField(
4829
        $initialLanguageCode,
4830
        $structFields,
4831
        $existingFields,
4832
        $fieldDefinitions
4833
    ) {
4834
        $repositoryMock = $this->getRepositoryMock();
4835
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
4836
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
4837
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
4838
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
4839
        $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...
4840
        $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...
4841
        $existingLanguageCodes = array_map(
4842
            function (Field $field) {
4843
                return $field->languageCode;
4844
            },
4845
            $existingFields
4846
        );
4847
        $versionInfo = new VersionInfo(
4848
            [
4849
                'contentInfo' => new ContentInfo(
4850
                    [
4851
                        'id' => 42,
4852
                        'contentTypeId' => 24,
4853
                        'mainLanguageCode' => 'eng-GB',
4854
                    ]
4855
                ),
4856
                'versionNo' => 7,
4857
                'languageCodes' => $existingLanguageCodes,
4858
                'status' => VersionInfo::STATUS_DRAFT,
4859
            ]
4860
        );
4861
        $content = new Content(
4862
            [
4863
                'versionInfo' => $versionInfo,
4864
                'internalFields' => $existingFields,
4865
            ]
4866
        );
4867
        $contentType = new ContentType(['fieldDefinitions' => $fieldDefinitions]);
4868
4869
        $languageHandlerMock->expects($this->any())
4870
            ->method('loadByLanguageCode')
4871
            ->with($this->isType('string'))
4872
            ->will(
4873
                $this->returnCallback(
4874
                    function () {
4875
                        return new Language(['id' => 4242]);
4876
                    }
4877
                )
4878
            );
4879
4880
        $mockedService->expects($this->once())
4881
            ->method('loadContent')
4882
            ->with(
4883
                $this->equalTo(42),
4884
                $this->equalTo(null),
4885
                $this->equalTo(7)
4886
            )->will(
4887
                $this->returnValue($content)
4888
            );
4889
4890
        $repositoryMock->expects($this->once())
4891
            ->method('canUser')
4892
            ->with(
4893
                $this->equalTo('content'),
4894
                $this->equalTo('edit'),
4895
                $this->equalTo($content)
4896
            )->will($this->returnValue(true));
4897
4898
        $contentTypeServiceMock->expects($this->once())
4899
            ->method('loadContentType')
4900
            ->with($this->equalTo(24))
4901
            ->will($this->returnValue($contentType));
4902
4903
        $repositoryMock->expects($this->once())
4904
            ->method('getContentTypeService')
4905
            ->will($this->returnValue($contentTypeServiceMock));
4906
4907
        $fieldTypeMock->expects($this->any())
4908
            ->method('acceptValue')
4909
            ->will(
4910
                $this->returnCallback(
4911
                    function ($valueString) {
4912
                        return new ValueStub($valueString);
4913
                    }
4914
                )
4915
            );
4916
4917
        $emptyValue = self::EMPTY_FIELD_VALUE;
4918
        $fieldTypeMock->expects($this->any())
4919
            ->method('isEmptyValue')
4920
            ->will(
4921
                $this->returnCallback(
4922
                    function (ValueStub $value) use ($emptyValue) {
4923
                        return $emptyValue === (string)$value;
4924
                    }
4925
                )
4926
            );
4927
4928
        $fieldTypeMock->expects($this->any())
4929
            ->method('validate')
4930
            ->with(
4931
                $this->isInstanceOf('eZ\\Publish\\API\\Repository\\Values\\ContentType\\FieldDefinition'),
4932
                $this->isInstanceOf('eZ\\Publish\\Core\\FieldType\\Value')
4933
            );
4934
4935
        $this->getFieldTypeRegistryMock()->expects($this->any())
4936
            ->method('getFieldType')
4937
            ->will($this->returnValue($fieldTypeMock));
4938
4939
        $contentUpdateStruct = new ContentUpdateStruct(
4940
            [
4941
                'fields' => $structFields,
4942
                'initialLanguageCode' => $initialLanguageCode,
4943
            ]
4944
        );
4945
4946
        return [$content->versionInfo, $contentUpdateStruct];
4947
    }
4948
4949 View Code Duplication
    public function providerForTestUpdateContentRequiredField()
4950
    {
4951
        return [
4952
            [
4953
                'eng-US',
4954
                [
4955
                    new Field(
4956
                        [
4957
                            'fieldDefIdentifier' => 'identifier',
4958
                            'value' => self::EMPTY_FIELD_VALUE,
4959
                            'languageCode' => null,
4960
                        ]
4961
                    ),
4962
                ],
4963
                'identifier',
4964
                'eng-US',
4965
            ],
4966
        ];
4967
    }
4968
4969
    /**
4970
     * Test for the updateContent() method.
4971
     *
4972
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
4973
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
4974
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
4975
     * @dataProvider providerForTestUpdateContentRequiredField
4976
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
4977
     */
4978
    public function testUpdateContentRequiredField(
4979
        $initialLanguageCode,
4980
        $structFields,
4981
        $identifier,
4982
        $languageCode
4983
    ) {
4984
        $existingFields = [
4985
            new Field(
4986
                [
4987
                    'id' => '100',
4988
                    'fieldDefIdentifier' => 'identifier',
4989
                    'value' => 'initialValue',
4990
                    'languageCode' => 'eng-GB',
4991
                ]
4992
            ),
4993
        ];
4994
        $fieldDefinitions = [
4995
            new FieldDefinition(
4996
                [
4997
                    'id' => 'fieldDefinitionId',
4998
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
4999
                    'isTranslatable' => true,
5000
                    'identifier' => 'identifier',
5001
                    'isRequired' => true,
5002
                    'defaultValue' => 'defaultValue',
5003
                ]
5004
            ),
5005
        ];
5006
        list($versionInfo, $contentUpdateStruct) =
5007
            $this->assertForTestUpdateContentRequiredField(
5008
                $initialLanguageCode,
5009
                $structFields,
5010
                $existingFields,
5011
                $fieldDefinitions
5012
            );
5013
5014
        try {
5015
            $this->partlyMockedContentService->updateContent($versionInfo, $contentUpdateStruct);
5016
        } catch (ContentValidationException $e) {
5017
            $this->assertEquals(
5018
                "Value for required field definition '{$identifier}' with language '{$languageCode}' is empty",
5019
                $e->getMessage()
5020
            );
5021
5022
            throw $e;
5023
        }
5024
    }
5025
5026
    public function assertForTestUpdateContentThrowsContentFieldValidationException(
5027
        $initialLanguageCode,
5028
        $structFields,
5029
        $existingFields,
5030
        $fieldDefinitions
5031
    ) {
5032
        $repositoryMock = $this->getRepositoryMock();
5033
        $mockedService = $this->getPartlyMockedContentService(['loadContent']);
5034
        /** @var \PHPUnit_Framework_MockObject_MockObject $languageHandlerMock */
5035
        $languageHandlerMock = $this->getPersistenceMock()->contentLanguageHandler();
5036
        $contentTypeServiceMock = $this->getContentTypeServiceMock();
5037
        $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...
5038
        $existingLanguageCodes = array_map(
5039
            function (Field $field) {
5040
                return $field->languageCode;
5041
            },
5042
            $existingFields
5043
        );
5044
        $languageCodes = $this->determineLanguageCodesForUpdate(
5045
            $initialLanguageCode,
5046
            $structFields,
5047
            $existingLanguageCodes
5048
        );
5049
        $versionInfo = new VersionInfo(
5050
            [
5051
                'contentInfo' => new ContentInfo(
5052
                    [
5053
                        'id' => 42,
5054
                        'contentTypeId' => 24,
5055
                        'mainLanguageCode' => 'eng-GB',
5056
                    ]
5057
                ),
5058
                'versionNo' => 7,
5059
                'languageCodes' => $existingLanguageCodes,
5060
                'status' => VersionInfo::STATUS_DRAFT,
5061
            ]
5062
        );
5063
        $content = new Content(
5064
            [
5065
                'versionInfo' => $versionInfo,
5066
                'internalFields' => $existingFields,
5067
            ]
5068
        );
5069
        $contentType = new ContentType(['fieldDefinitions' => $fieldDefinitions]);
5070
5071
        $languageHandlerMock->expects($this->any())
5072
            ->method('loadByLanguageCode')
5073
            ->with($this->isType('string'))
5074
            ->will(
5075
                $this->returnCallback(
5076
                    function () {
5077
                        return new Language(['id' => 4242]);
5078
                    }
5079
                )
5080
            );
5081
5082
        $mockedService->expects($this->once())
5083
            ->method('loadContent')
5084
            ->with(
5085
                $this->equalTo(42),
5086
                $this->equalTo(null),
5087
                $this->equalTo(7)
5088
            )->will(
5089
                $this->returnValue($content)
5090
            );
5091
5092
        $repositoryMock->expects($this->once())
5093
            ->method('canUser')
5094
            ->with(
5095
                $this->equalTo('content'),
5096
                $this->equalTo('edit'),
5097
                $this->equalTo($content)
5098
            )->will($this->returnValue(true));
5099
5100
        $contentTypeServiceMock->expects($this->once())
5101
            ->method('loadContentType')
5102
            ->with($this->equalTo(24))
5103
            ->will($this->returnValue($contentType));
5104
5105
        $repositoryMock->expects($this->once())
5106
            ->method('getContentTypeService')
5107
            ->will($this->returnValue($contentTypeServiceMock));
5108
5109
        $fieldValues = $this->determineValuesForUpdate(
5110
            $initialLanguageCode,
5111
            $structFields,
5112
            $content,
5113
            $fieldDefinitions,
5114
            $languageCodes
5115
        );
5116
        $allFieldErrors = [];
5117
        $emptyValue = self::EMPTY_FIELD_VALUE;
5118
5119
        $fieldTypeMock->expects($this->exactly(count($fieldValues) * count($languageCodes)))
5120
            ->method('acceptValue')
5121
            ->will(
5122
                $this->returnCallback(
5123
                    function ($valueString) {
5124
                        return new ValueStub($valueString);
5125
                    }
5126
                )
5127
            );
5128
5129
        $fieldTypeMock->expects($this->exactly(count($fieldValues) * count($languageCodes)))
5130
            ->method('isEmptyValue')
5131
            ->will(
5132
                $this->returnCallback(
5133
                    function (ValueStub $value) use ($emptyValue) {
5134
                        return $emptyValue === (string)$value;
5135
                    }
5136
                )
5137
            );
5138
5139
        $fieldTypeMock
5140
            ->expects($this->any())
5141
            ->method('validate')
5142
            ->willReturnArgument(1);
5143
5144
        $this->getFieldTypeRegistryMock()->expects($this->any())
5145
            ->method('getFieldType')
5146
            ->will($this->returnValue($fieldTypeMock));
5147
5148
        $contentUpdateStruct = new ContentUpdateStruct(
5149
            [
5150
                'fields' => $structFields,
5151
                'initialLanguageCode' => $initialLanguageCode,
5152
            ]
5153
        );
5154
5155
        return [$content->versionInfo, $contentUpdateStruct, $allFieldErrors];
5156
    }
5157
5158
    public function providerForTestUpdateContentThrowsContentFieldValidationException()
5159
    {
5160
        $allFieldErrors = [
5161
            [
5162
                'fieldDefinitionId1' => [
5163
                    'eng-GB' => 'newValue1-eng-GB',
5164
                    'eng-US' => 'newValue1-eng-GB',
5165
                ],
5166
                'fieldDefinitionId2' => [
5167
                    'eng-GB' => 'initialValue2',
5168
                ],
5169
                'fieldDefinitionId3' => [
5170
                    'eng-GB' => 'initialValue3',
5171
                    'eng-US' => 'initialValue3',
5172
                ],
5173
                'fieldDefinitionId4' => [
5174
                    'eng-GB' => 'initialValue4',
5175
                    'eng-US' => 'newValue4',
5176
                ],
5177
            ],
5178
            [
5179
                'fieldDefinitionId1' => [
5180
                    'eng-GB' => 'newValue1-eng-GB',
5181
                    'eng-US' => 'newValue1-eng-GB',
5182
                ],
5183
                'fieldDefinitionId2' => [
5184
                    'eng-GB' => 'initialValue2',
5185
                ],
5186
                'fieldDefinitionId3' => [
5187
                    'eng-GB' => 'initialValue3',
5188
                    'eng-US' => 'initialValue3',
5189
                ],
5190
                'fieldDefinitionId4' => [
5191
                    'eng-GB' => 'initialValue4',
5192
                    'eng-US' => 'newValue4',
5193
                ],
5194
            ],
5195
            [
5196
                'fieldDefinitionId1' => [
5197
                    'eng-GB' => 'newValue1-eng-GB',
5198
                    'eng-US' => 'newValue1-eng-GB',
5199
                ],
5200
                'fieldDefinitionId2' => [
5201
                    'eng-GB' => 'initialValue2',
5202
                    'eng-US' => 'newValue2',
5203
                ],
5204
                'fieldDefinitionId3' => [
5205
                    'eng-GB' => 'initialValue3',
5206
                    'eng-US' => 'initialValue3',
5207
                ],
5208
                'fieldDefinitionId4' => [
5209
                    'eng-GB' => 'initialValue4',
5210
                    'eng-US' => 'defaultValue4',
5211
                ],
5212
            ],
5213
            [
5214
                'fieldDefinitionId1' => [
5215
                    'eng-GB' => 'newValue1-eng-GB',
5216
                    'eng-US' => 'newValue1-eng-GB',
5217
                ],
5218
                'fieldDefinitionId2' => [
5219
                    'eng-GB' => 'initialValue2',
5220
                    'eng-US' => 'newValue2',
5221
                ],
5222
                'fieldDefinitionId3' => [
5223
                    'eng-GB' => 'initialValue3',
5224
                    'eng-US' => 'initialValue3',
5225
                ],
5226
                'fieldDefinitionId4' => [
5227
                    'eng-GB' => 'initialValue4',
5228
                    'eng-US' => 'defaultValue4',
5229
                ],
5230
            ],
5231
            [
5232
                'fieldDefinitionId1' => [
5233
                    'eng-GB' => 'newValue1-eng-GB',
5234
                    'ger-DE' => 'newValue1-eng-GB',
5235
                    'eng-US' => 'newValue1-eng-GB',
5236
                ],
5237
                'fieldDefinitionId2' => [
5238
                    'eng-GB' => 'initialValue2',
5239
                    'eng-US' => 'newValue2',
5240
                ],
5241
                'fieldDefinitionId3' => [
5242
                    'eng-GB' => 'initialValue3',
5243
                    'ger-DE' => 'initialValue3',
5244
                    'eng-US' => 'initialValue3',
5245
                ],
5246
                'fieldDefinitionId4' => [
5247
                    'eng-GB' => 'initialValue4',
5248
                    'eng-US' => 'defaultValue4',
5249
                    'ger-DE' => 'defaultValue4',
5250
                ],
5251
            ],
5252
            [
5253
                'fieldDefinitionId1' => [
5254
                    'eng-US' => 'newValue1-eng-GB',
5255
                    'ger-DE' => 'newValue1-eng-GB',
5256
                ],
5257
                'fieldDefinitionId2' => [
5258
                    'eng-US' => 'newValue2',
5259
                ],
5260
                'fieldDefinitionId3' => [
5261
                    'ger-DE' => 'initialValue3',
5262
                    'eng-US' => 'initialValue3',
5263
                ],
5264
                'fieldDefinitionId4' => [
5265
                    'ger-DE' => 'defaultValue4',
5266
                    'eng-US' => 'defaultValue4',
5267
                ],
5268
            ],
5269
        ];
5270
5271
        $data = $this->providerForTestUpdateContentNonRedundantFieldSetComplex();
5272
        $count = count($data);
5273
        for ($i = 0; $i < $count; ++$i) {
5274
            $data[$i][] = $allFieldErrors[$i];
5275
        }
5276
5277
        return $data;
5278
    }
5279
5280
    /**
5281
     * Test for the updateContent() method.
5282
     *
5283
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
5284
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
5285
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
5286
     * @dataProvider providerForTestUpdateContentThrowsContentFieldValidationException
5287
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
5288
     * @expectedExceptionMessage Content fields did not validate
5289
     */
5290
    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...
5291
    {
5292
        list($existingFields, $fieldDefinitions) = $this->fixturesForTestUpdateContentNonRedundantFieldSetComplex();
5293
        list($versionInfo, $contentUpdateStruct) =
5294
            $this->assertForTestUpdateContentThrowsContentFieldValidationException(
5295
                $initialLanguageCode,
5296
                $structFields,
5297
                $existingFields,
5298
                $fieldDefinitions
5299
            );
5300
5301
        try {
5302
            $this->partlyMockedContentService->updateContent($versionInfo, $contentUpdateStruct);
5303
        } catch (ContentFieldValidationException $e) {
5304
            $this->assertEquals($allFieldErrors, $e->getFieldErrors());
5305
            throw $e;
5306
        }
5307
    }
5308
5309
    /**
5310
     * Test for the updateContent() method.
5311
     *
5312
     * @covers \eZ\Publish\Core\Repository\ContentService::getLanguageCodesForUpdate
5313
     * @covers \eZ\Publish\Core\Repository\ContentService::mapFieldsForUpdate
5314
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContent
5315
     * @expectedException \Exception
5316
     * @expectedExceptionMessage Store failed
5317
     */
5318
    public function testUpdateContentTransactionRollback()
5319
    {
5320
        $existingFields = [
5321
            new Field(
5322
                [
5323
                    'id' => '100',
5324
                    'fieldDefIdentifier' => 'identifier',
5325
                    'value' => 'initialValue',
5326
                    'languageCode' => 'eng-GB',
5327
                ]
5328
            ),
5329
        ];
5330
5331
        $fieldDefinitions = [
5332
            new FieldDefinition(
5333
                [
5334
                    'id' => 'fieldDefinitionId',
5335
                    'fieldTypeIdentifier' => 'fieldTypeIdentifier',
5336
                    'isTranslatable' => false,
5337
                    'identifier' => 'identifier',
5338
                    'isRequired' => false,
5339
                    'defaultValue' => 'defaultValue',
5340
                ]
5341
            ),
5342
        ];
5343
5344
        // Setup a simple case that will pass
5345
        list($versionInfo, $contentUpdateStruct) = $this->assertForTestUpdateContentNonRedundantFieldSet(
5346
            'eng-US',
5347
            [],
5348
            [],
5349
            $existingFields,
5350
            $fieldDefinitions,
5351
            // Do not execute test
5352
            false
5353
        );
5354
5355
        $repositoryMock = $this->getRepositoryMock();
5356
        $repositoryMock->expects($this->never())->method('commit');
5357
        $repositoryMock->expects($this->once())->method('rollback');
5358
5359
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5360
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5361
        $contentHandlerMock->expects($this->once())
5362
            ->method('updateContent')
5363
            ->with(
5364
                $this->anything(),
5365
                $this->anything(),
5366
                $this->anything()
5367
            )->will($this->throwException(new \Exception('Store failed')));
5368
5369
        // Execute
5370
        $this->partlyMockedContentService->updateContent($versionInfo, $contentUpdateStruct);
5371
    }
5372
5373
    /**
5374
     * Test for the copyContent() method.
5375
     *
5376
     * @covers \eZ\Publish\Core\Repository\ContentService::copyContent
5377
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
5378
     */
5379
    public function testCopyContentThrowsUnauthorizedException()
5380
    {
5381
        $repository = $this->getRepositoryMock();
5382
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo']);
5383
        $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...
5384
        $locationCreateStruct = new LocationCreateStruct();
5385
        $location = new Location(['id' => $locationCreateStruct->parentLocationId]);
5386
        $locationServiceMock = $this->getLocationServiceMock();
5387
5388
        $repository->expects($this->once())
5389
            ->method('getLocationService')
5390
            ->will($this->returnValue($locationServiceMock))
5391
        ;
5392
5393
        $locationServiceMock->expects($this->once())
5394
            ->method('loadLocation')
5395
            ->with(
5396
                $locationCreateStruct->parentLocationId
5397
            )
5398
            ->will($this->returnValue($location))
5399
        ;
5400
5401
        $contentInfo->expects($this->any())
5402
            ->method('__get')
5403
            ->with('sectionId')
5404
            ->will($this->returnValue(42));
5405
5406
        $repository->expects($this->once())
5407
            ->method('canUser')
5408
            ->with(
5409
                'content',
5410
                'create',
5411
                $contentInfo,
5412
                [$location]
5413
            )
5414
            ->will($this->returnValue(false));
5415
5416
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo */
5417
        $contentService->copyContent($contentInfo, $locationCreateStruct);
5418
    }
5419
5420
    /**
5421
     * Test for the copyContent() method.
5422
     *
5423
     * @covers \eZ\Publish\Core\Repository\ContentService::copyContent
5424
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
5425
     * @covers \eZ\Publish\Core\Repository\ContentService::internalPublishVersion
5426
     */
5427
    public function testCopyContent()
5428
    {
5429
        $repositoryMock = $this->getRepositoryMock();
5430
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo', 'internalLoadContent']);
5431
        $locationServiceMock = $this->getLocationServiceMock();
5432
        $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...
5433
        $locationCreateStruct = new LocationCreateStruct();
5434
        $location = new Location(['id' => $locationCreateStruct->parentLocationId]);
5435
        $user = $this->getStubbedUser(14);
5436
5437
        $permissionResolverMock = $this
5438
            ->getMockBuilder('eZ\\Publish\\API\\Repository\\PermissionResolver')
5439
            ->disableOriginalConstructor()
5440
            ->getMock();
5441
5442
        $permissionResolverMock
5443
            ->method('getCurrentUserReference')
5444
            ->willReturn($user);
5445
5446
        $repositoryMock
5447
            ->method('getPermissionResolver')
5448
            ->willReturn($permissionResolverMock);
5449
5450
        $repositoryMock->expects($this->exactly(3))
5451
            ->method('getLocationService')
5452
            ->will($this->returnValue($locationServiceMock));
5453
5454
        $locationServiceMock->expects($this->once())
5455
            ->method('loadLocation')
5456
            ->with($locationCreateStruct->parentLocationId)
5457
            ->will($this->returnValue($location))
5458
        ;
5459
5460
        $contentInfoMock->expects($this->any())
5461
            ->method('__get')
5462
            ->with('id')
5463
            ->will($this->returnValue(42));
5464
        $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...
5465
5466
        $versionInfoMock->expects($this->any())
5467
            ->method('__get')
5468
            ->will(
5469
                $this->returnValueMap(
5470
                    [
5471
                        ['versionNo', 123],
5472
                        ['status', VersionInfo::STATUS_DRAFT],
5473
                    ]
5474
                )
5475
            );
5476
        $versionInfoMock->expects($this->once())
5477
            ->method('getContentInfo')
5478
            ->will($this->returnValue($contentInfoMock));
5479
5480
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5481
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5482
        $domainMapperMock = $this->getDomainMapperMock();
5483
5484
        $repositoryMock->expects($this->once())->method('beginTransaction');
5485
        $repositoryMock->expects($this->once())->method('commit');
5486
        $repositoryMock->expects($this->once())
5487
            ->method('canUser')
5488
            ->with(
5489
                'content',
5490
                'create',
5491
                $contentInfoMock,
5492
                [$location]
5493
            )
5494
            ->will($this->returnValue(true));
5495
5496
        $spiContentInfo = new SPIContentInfo(['id' => 42]);
5497
        $spiVersionInfo = new SPIVersionInfo(
5498
            [
5499
                'contentInfo' => $spiContentInfo,
5500
                'creationDate' => 123456,
5501
            ]
5502
        );
5503
        $spiContent = new SPIContent(['versionInfo' => $spiVersionInfo]);
5504
        $contentHandlerMock->expects($this->once())
5505
            ->method('copy')
5506
            ->with(42, null)
5507
            ->will($this->returnValue($spiContent));
5508
5509
        $this->mockGetDefaultObjectStates();
5510
        $this->mockSetDefaultObjectStates();
5511
5512
        $domainMapperMock->expects($this->once())
5513
            ->method('buildVersionInfoDomainObject')
5514
            ->with($spiVersionInfo)
5515
            ->will($this->returnValue($versionInfoMock));
5516
5517
        /* @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfoMock */
5518
        $content = $this->mockPublishVersion(123456);
5519
        $locationServiceMock->expects($this->once())
5520
            ->method('createLocation')
5521
            ->with(
5522
                $content->getVersionInfo()->getContentInfo(),
5523
                $locationCreateStruct
5524
            );
5525
5526
        $contentService->expects($this->once())
5527
            ->method('internalLoadContent')
5528
            ->with(
5529
                $content->id
5530
            )
5531
            ->will($this->returnValue($content));
5532
5533
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfoMock */
5534
        $contentService->copyContent($contentInfoMock, $locationCreateStruct, null);
5535
    }
5536
5537
    /**
5538
     * Test for the copyContent() method.
5539
     *
5540
     * @covers \eZ\Publish\Core\Repository\ContentService::copyContent
5541
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
5542
     * @covers \eZ\Publish\Core\Repository\ContentService::internalPublishVersion
5543
     */
5544
    public function testCopyContentWithVersionInfo()
5545
    {
5546
        $repositoryMock = $this->getRepositoryMock();
5547
        $contentService = $this->getPartlyMockedContentService(['internalLoadContentInfo', 'internalLoadContent']);
5548
        $locationServiceMock = $this->getLocationServiceMock();
5549
        $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...
5550
        $locationCreateStruct = new LocationCreateStruct();
5551
        $location = new Location(['id' => $locationCreateStruct->parentLocationId]);
5552
        $user = $this->getStubbedUser(14);
5553
5554
        $permissionResolverMock = $this
5555
            ->getMockBuilder('eZ\\Publish\\API\\Repository\\PermissionResolver')
5556
            ->disableOriginalConstructor()
5557
            ->getMock();
5558
5559
        $permissionResolverMock
5560
            ->method('getCurrentUserReference')
5561
            ->willReturn($user);
5562
5563
        $repositoryMock
5564
            ->method('getPermissionResolver')
5565
            ->willReturn($permissionResolverMock);
5566
5567
        $repositoryMock->expects($this->exactly(3))
5568
            ->method('getLocationService')
5569
            ->will($this->returnValue($locationServiceMock));
5570
5571
        $locationServiceMock->expects($this->once())
5572
            ->method('loadLocation')
5573
            ->with($locationCreateStruct->parentLocationId)
5574
            ->will($this->returnValue($location))
5575
        ;
5576
5577
        $contentInfoMock->expects($this->any())
5578
            ->method('__get')
5579
            ->with('id')
5580
            ->will($this->returnValue(42));
5581
        $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...
5582
5583
        $versionInfoMock->expects($this->any())
5584
            ->method('__get')
5585
            ->will(
5586
                $this->returnValueMap(
5587
                    [
5588
                        ['versionNo', 123],
5589
                        ['status', VersionInfo::STATUS_DRAFT],
5590
                    ]
5591
                )
5592
            );
5593
        $versionInfoMock->expects($this->once())
5594
            ->method('getContentInfo')
5595
            ->will($this->returnValue($contentInfoMock));
5596
5597
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5598
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5599
        $domainMapperMock = $this->getDomainMapperMock();
5600
5601
        $repositoryMock->expects($this->once())->method('beginTransaction');
5602
        $repositoryMock->expects($this->once())->method('commit');
5603
        $repositoryMock->expects($this->once())
5604
            ->method('canUser')
5605
            ->with(
5606
                'content',
5607
                'create',
5608
                $contentInfoMock,
5609
                [$location]
5610
            )
5611
            ->will($this->returnValue(true));
5612
5613
        $spiContentInfo = new SPIContentInfo(['id' => 42]);
5614
        $spiVersionInfo = new SPIVersionInfo(
5615
            [
5616
                'contentInfo' => $spiContentInfo,
5617
                'creationDate' => 123456,
5618
            ]
5619
        );
5620
        $spiContent = new SPIContent(['versionInfo' => $spiVersionInfo]);
5621
        $contentHandlerMock->expects($this->once())
5622
            ->method('copy')
5623
            ->with(42, 123)
5624
            ->will($this->returnValue($spiContent));
5625
5626
        $this->mockGetDefaultObjectStates();
5627
        $this->mockSetDefaultObjectStates();
5628
5629
        $domainMapperMock->expects($this->once())
5630
            ->method('buildVersionInfoDomainObject')
5631
            ->with($spiVersionInfo)
5632
            ->will($this->returnValue($versionInfoMock));
5633
5634
        /* @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfoMock */
5635
        $content = $this->mockPublishVersion(123456);
5636
        $locationServiceMock->expects($this->once())
5637
            ->method('createLocation')
5638
            ->with(
5639
                $content->getVersionInfo()->getContentInfo(),
5640
                $locationCreateStruct
5641
            );
5642
5643
        $contentService->expects($this->once())
5644
            ->method('internalLoadContent')
5645
            ->with(
5646
                $content->id
5647
            )
5648
            ->will($this->returnValue($content));
5649
5650
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfoMock */
5651
        $contentService->copyContent($contentInfoMock, $locationCreateStruct, $versionInfoMock);
5652
    }
5653
5654
    /**
5655
     * Test for the copyContent() method.
5656
     *
5657
     * @covers \eZ\Publish\Core\Repository\ContentService::copyContent
5658
     * @covers \eZ\Publish\Core\Repository\ContentService::getDefaultObjectStates
5659
     * @covers \eZ\Publish\Core\Repository\ContentService::internalPublishVersion
5660
     * @expectedException \Exception
5661
     * @expectedExceptionMessage Handler threw an exception
5662
     */
5663
    public function testCopyContentWithRollback()
5664
    {
5665
        $repositoryMock = $this->getRepositoryMock();
5666
        $contentService = $this->getPartlyMockedContentService();
5667
        /** @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5668
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5669
        $locationCreateStruct = new LocationCreateStruct();
5670
        $location = new Location(['id' => $locationCreateStruct->parentLocationId]);
5671
        $locationServiceMock = $this->getLocationServiceMock();
5672
        $user = $this->getStubbedUser(14);
5673
5674
        $permissionResolverMock = $this
5675
            ->getMockBuilder('eZ\\Publish\\API\\Repository\\PermissionResolver')
5676
            ->disableOriginalConstructor()
5677
            ->getMock();
5678
5679
        $permissionResolverMock
5680
            ->method('getCurrentUserReference')
5681
            ->willReturn($user);
5682
5683
        $repositoryMock
5684
            ->method('getPermissionResolver')
5685
            ->willReturn($permissionResolverMock);
5686
5687
        $repositoryMock->expects($this->once())
5688
            ->method('getLocationService')
5689
            ->will($this->returnValue($locationServiceMock))
5690
        ;
5691
5692
        $locationServiceMock->expects($this->once())
5693
            ->method('loadLocation')
5694
            ->with($locationCreateStruct->parentLocationId)
5695
            ->will($this->returnValue($location))
5696
        ;
5697
5698
        $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...
5699
        $contentInfoMock->expects($this->any())
5700
            ->method('__get')
5701
            ->with('id')
5702
            ->will($this->returnValue(42));
5703
5704
        $this->mockGetDefaultObjectStates();
5705
5706
        $repositoryMock->expects($this->once())->method('beginTransaction');
5707
        $repositoryMock->expects($this->once())->method('rollback');
5708
        $repositoryMock->expects($this->once())
5709
            ->method('canUser')
5710
            ->with(
5711
                'content',
5712
                'create',
5713
                $contentInfoMock,
5714
                [$location]
5715
            )
5716
            ->will($this->returnValue(true));
5717
5718
        $contentHandlerMock->expects($this->once())
5719
            ->method('copy')
5720
            ->with(42, null)
5721
            ->will($this->throwException(new Exception('Handler threw an exception')));
5722
5723
        /* @var \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfoMock */
5724
        $contentService->copyContent($contentInfoMock, $locationCreateStruct, null);
5725
    }
5726
5727
    protected function mockGetDefaultObjectStates()
5728
    {
5729
        /** @var \PHPUnit_Framework_MockObject_MockObject $objectStateHandlerMock */
5730
        $objectStateHandlerMock = $this->getPersistenceMock()->objectStateHandler();
5731
5732
        $objectStateGroups = [
5733
            new SPIObjectStateGroup(['id' => 10]),
5734
            new SPIObjectStateGroup(['id' => 20]),
5735
        ];
5736
5737
        /* @var \PHPUnit_Framework_MockObject_MockObject $objectStateHandlerMock */
5738
        $objectStateHandlerMock->expects($this->once())
5739
            ->method('loadAllGroups')
5740
            ->will($this->returnValue($objectStateGroups));
5741
5742
        $objectStateHandlerMock->expects($this->at(1))
5743
            ->method('loadObjectStates')
5744
            ->with($this->equalTo(10))
5745
            ->will(
5746
                $this->returnValue(
5747
                    [
5748
                        new SPIObjectState(['id' => 11, 'groupId' => 10]),
5749
                        new SPIObjectState(['id' => 12, 'groupId' => 10]),
5750
                    ]
5751
                )
5752
            );
5753
5754
        $objectStateHandlerMock->expects($this->at(2))
5755
            ->method('loadObjectStates')
5756
            ->with($this->equalTo(20))
5757
            ->will(
5758
                $this->returnValue(
5759
                    [
5760
                        new SPIObjectState(['id' => 21, 'groupId' => 20]),
5761
                        new SPIObjectState(['id' => 22, 'groupId' => 20]),
5762
                    ]
5763
                )
5764
            );
5765
    }
5766
5767
    protected function mockSetDefaultObjectStates()
5768
    {
5769
        /** @var \PHPUnit_Framework_MockObject_MockObject $objectStateHandlerMock */
5770
        $objectStateHandlerMock = $this->getPersistenceMock()->objectStateHandler();
5771
5772
        $defaultObjectStates = [
5773
            new SPIObjectState(['id' => 11, 'groupId' => 10]),
5774
            new SPIObjectState(['id' => 21, 'groupId' => 20]),
5775
        ];
5776
        foreach ($defaultObjectStates as $index => $objectState) {
5777
            $objectStateHandlerMock->expects($this->at($index + 3))
5778
                ->method('setContentState')
5779
                ->with(
5780
                    42,
5781
                    $objectState->groupId,
5782
                    $objectState->id
5783
                );
5784
        }
5785
    }
5786
5787
    /**
5788
     * @param int|null $publicationDate
5789
     *
5790
     * @return \eZ\Publish\API\Repository\Values\Content\Content
5791
     */
5792
    protected function mockPublishVersion($publicationDate = null)
5793
    {
5794
        $domainMapperMock = $this->getDomainMapperMock();
5795
        $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...
5796
        /* @var \PHPUnit_Framework_MockObject_MockObject $contentHandlerMock */
5797
        $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...
5798
        $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...
5799
        $contentHandlerMock = $this->getPersistenceMock()->contentHandler();
5800
        $metadataUpdateStruct = new SPIMetadataUpdateStruct();
5801
5802
        $contentMock->expects($this->any())
5803
            ->method('__get')
5804
            ->will(
5805
                $this->returnValueMap(
5806
                    [
5807
                        ['id', 42],
5808
                        ['contentInfo', $contentInfoMock],
5809
                    ]
5810
                )
5811
            );
5812
        $contentMock->expects($this->any())
5813
            ->method('getVersionInfo')
5814
            ->will($this->returnValue($versionInfoMock));
5815
        $versionInfoMock->expects($this->any())
5816
            ->method('getContentInfo')
5817
            ->will($this->returnValue($contentInfoMock));
5818
        $contentInfoMock->expects($this->any())
5819
            ->method('__get')
5820
            ->will(
5821
                $this->returnValueMap(
5822
                    [
5823
                        ['alwaysAvailable', true],
5824
                        ['mainLanguageCode', 'eng-GB'],
5825
                    ]
5826
                )
5827
            );
5828
5829
        $currentTime = time();
5830
        if ($publicationDate === null && $versionInfoMock->versionNo === 1) {
5831
            $publicationDate = $currentTime;
5832
        }
5833
5834
        // Account for 1 second of test execution time
5835
        $metadataUpdateStruct->publicationDate = $publicationDate;
5836
        $metadataUpdateStruct->modificationDate = $currentTime;
5837
        $metadataUpdateStruct2 = clone $metadataUpdateStruct;
5838
        ++$metadataUpdateStruct2->publicationDate;
5839
        ++$metadataUpdateStruct2->modificationDate;
5840
5841
        $spiContent = new SPIContent();
5842
        $contentHandlerMock->expects($this->once())
5843
            ->method('publish')
5844
            ->with(
5845
                42,
5846
                123,
5847
                $this->logicalOr($metadataUpdateStruct, $metadataUpdateStruct2)
5848
            )
5849
            ->will($this->returnValue($spiContent));
5850
5851
        $domainMapperMock->expects($this->once())
5852
            ->method('buildContentDomainObject')
5853
            ->with($spiContent)
5854
            ->will($this->returnValue($contentMock));
5855
5856
        /* @var \eZ\Publish\API\Repository\Values\Content\Content $contentMock */
5857
        $this->mockPublishUrlAliasesForContent($contentMock);
5858
5859
        return $contentMock;
5860
    }
5861
5862
    /**
5863
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
5864
     */
5865
    protected function mockPublishUrlAliasesForContent(APIContent $content)
5866
    {
5867
        $nameSchemaServiceMock = $this->getNameSchemaServiceMock();
5868
        /** @var \PHPUnit_Framework_MockObject_MockObject $urlAliasHandlerMock */
5869
        $urlAliasHandlerMock = $this->getPersistenceMock()->urlAliasHandler();
5870
        $locationServiceMock = $this->getLocationServiceMock();
5871
        $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...
5872
5873
        $location->expects($this->at(0))
5874
            ->method('__get')
5875
            ->with('id')
5876
            ->will($this->returnValue(123));
5877
        $location->expects($this->at(1))
5878
            ->method('__get')
5879
            ->with('parentLocationId')
5880
            ->will($this->returnValue(456));
5881
5882
        $urlAliasNames = ['eng-GB' => 'hello'];
5883
        $nameSchemaServiceMock->expects($this->once())
5884
            ->method('resolveUrlAliasSchema')
5885
            ->with($content)
5886
            ->will($this->returnValue($urlAliasNames));
5887
5888
        $locationServiceMock->expects($this->once())
5889
            ->method('loadLocations')
5890
            ->with($content->getVersionInfo()->getContentInfo())
5891
            ->will($this->returnValue([$location]));
5892
5893
        $urlAliasHandlerMock->expects($this->once())
5894
            ->method('publishUrlAliasForLocation')
5895
            ->with(123, 456, 'hello', 'eng-GB', true, true);
5896
    }
5897
5898
    protected $domainMapperMock;
5899
5900
    /**
5901
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\Core\Repository\Helper\DomainMapper
5902
     */
5903 View Code Duplication
    protected function getDomainMapperMock()
5904
    {
5905
        if (!isset($this->domainMapperMock)) {
5906
            $this->domainMapperMock = $this
5907
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Helper\\DomainMapper')
5908
                ->disableOriginalConstructor()
5909
                ->getMock();
5910
        }
5911
5912
        return $this->domainMapperMock;
5913
    }
5914
5915
    protected $relationProcessorMock;
5916
5917
    /**
5918
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\Core\Repository\Helper\RelationProcessor
5919
     */
5920
    protected function getRelationProcessorMock()
5921
    {
5922
        if (!isset($this->relationProcessorMock)) {
5923
            $this->relationProcessorMock = $this
5924
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Helper\\RelationProcessor')
5925
                ->disableOriginalConstructor()
5926
                ->getMock();
5927
        }
5928
5929
        return $this->relationProcessorMock;
5930
    }
5931
5932
    protected $nameSchemaServiceMock;
5933
5934
    /**
5935
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\Core\Repository\Helper\NameSchemaService
5936
     */
5937
    protected function getNameSchemaServiceMock()
5938
    {
5939
        if (!isset($this->nameSchemaServiceMock)) {
5940
            $this->nameSchemaServiceMock = $this
5941
                ->getMockBuilder('eZ\\Publish\\Core\\Repository\\Helper\\NameSchemaService')
5942
                ->disableOriginalConstructor()
5943
                ->getMock();
5944
        }
5945
5946
        return $this->nameSchemaServiceMock;
5947
    }
5948
5949
    protected $contentTypeServiceMock;
5950
5951
    /**
5952
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\API\Repository\ContentTypeService
5953
     */
5954
    protected function getContentTypeServiceMock()
5955
    {
5956
        if (!isset($this->contentTypeServiceMock)) {
5957
            $this->contentTypeServiceMock = $this
5958
                ->getMockBuilder('eZ\\Publish\\API\\Repository\\ContentTypeService')
5959
                ->disableOriginalConstructor()
5960
                ->getMock();
5961
        }
5962
5963
        return $this->contentTypeServiceMock;
5964
    }
5965
5966
    protected $locationServiceMock;
5967
5968
    /**
5969
     * @return \PHPUnit_Framework_MockObject_MockObject|\eZ\Publish\API\Repository\LocationService
5970
     */
5971
    protected function getLocationServiceMock()
5972
    {
5973
        if (!isset($this->locationServiceMock)) {
5974
            $this->locationServiceMock = $this
5975
                ->getMockBuilder('eZ\\Publish\\API\\Repository\\LocationService')
5976
                ->disableOriginalConstructor()
5977
                ->getMock();
5978
        }
5979
5980
        return $this->locationServiceMock;
5981
    }
5982
5983
    /**
5984
     * @var \eZ\Publish\Core\Repository\ContentService
5985
     */
5986
    protected $partlyMockedContentService;
5987
5988
    /**
5989
     * Returns the content service to test with $methods mocked.
5990
     *
5991
     * Injected Repository comes from {@see getRepositoryMock()} and persistence handler from {@see getPersistenceMock()}
5992
     *
5993
     * @param string[] $methods
5994
     *
5995
     * @return \eZ\Publish\Core\Repository\ContentService|\PHPUnit_Framework_MockObject_MockObject
5996
     */
5997
    protected function getPartlyMockedContentService(array $methods = null)
5998
    {
5999
        if (!isset($this->partlyMockedContentService)) {
6000
            $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...
6001
                'eZ\\Publish\\Core\\Repository\\ContentService',
6002
                $methods,
0 ignored issues
show
Bug introduced by
It seems like $methods defined by parameter $methods on line 5997 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...
6003
                [
6004
                    $this->getRepositoryMock(),
6005
                    $this->getPersistenceMock(),
6006
                    $this->getDomainMapperMock(),
6007
                    $this->getRelationProcessorMock(),
6008
                    $this->getNameSchemaServiceMock(),
6009
                    $this->getFieldTypeRegistryMock(),
6010
                    [],
6011
                ]
6012
            );
6013
        }
6014
6015
        return $this->partlyMockedContentService;
6016
    }
6017
}
6018