Completed
Push — 7.0 ( 7b47bc...b7670c )
by André
132:42 queued 114:32
created

providerForTestUpdateContentThrowsContentFieldValidationException()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 121
Code Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 79
nc 2
nop 0
dl 0
loc 121
rs 8.2857
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

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