Completed
Push — master ( 6a9705...322f11 )
by
unknown
27:56
created

testLoadVersionInfoByIdThrowsUnauthorizedExceptionNonPublishedVersion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

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

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
6024
                ->setMethods($methods)
6025
                ->setConstructorArgs(
6026
                    array(
6027
                        $this->getRepositoryMock(),
6028
                        $this->getPersistenceMock(),
6029
                        $this->getDomainMapperMock(),
6030
                        $this->getRelationProcessorMock(),
6031
                        $this->getNameSchemaServiceMock(),
6032
                        $this->getFieldTypeRegistryMock(),
6033
                        array(),
6034
                    )
6035
                )
6036
                ->getMock();
6037
        }
6038
6039
        return $this->partlyMockedContentService;
6040
    }
6041
6042
    /**
6043
     * @return \eZ\Publish\API\Repository\Repository|\PHPUnit\Framework\MockObject\MockObject
6044
     */
6045
    protected function getRepositoryMock(): Repository
6046
    {
6047
        $repositoryMock = parent::getRepositoryMock();
6048
        $repositoryMock
6049
            ->expects($this->any())
6050
            ->method('getPermissionResolver')
6051
            ->willReturn($this->getPermissionResolverMock());
6052
6053
        return $repositoryMock;
6054
    }
6055
}
6056