testLoadContentTypeGroupsIdentifiers()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Publish\API\Repository\Tests;
8
9
use eZ\Publish\API\Repository\Values\Content\Language;
10
use eZ\Publish\API\Repository\Values\Content\Location;
11
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
12
use eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup;
13
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
14
use eZ\Publish\API\Repository\Exceptions\ContentTypeFieldDefinitionValidationException;
15
use eZ\Publish\API\Repository\Values\ContentType\FieldDefinition;
16
use eZ\Publish\API\Repository\Values\ContentType\FieldDefinitionCollection as APIFieldDefinitionCollection;
17
use eZ\Publish\API\Repository\Values\Translation\Message;
18
use Exception;
19
use eZ\Publish\Core\FieldType\TextLine\Value as TextLineValue;
20
21
/**
22
 * Test case for operations in the ContentTypeService using in memory storage.
23
 *
24
 * @see eZ\Publish\API\Repository\ContentTypeService
25
 * @group integration
26
 * @group content-type
27
 */
28
class ContentTypeServiceTest extends BaseContentTypeServiceTest
29
{
30
    /**
31
     * Test for the newContentTypeGroupCreateStruct() method.
32
     *
33
     * @see \eZ\Publish\API\Repository\ContentTypeService::newContentTypeGroupCreateStruct()
34
     * @group user
35
     */
36
    public function testNewContentTypeGroupCreateStruct()
37
    {
38
        $repository = $this->getRepository();
39
40
        /* BEGIN: Use Case */
41
        $contentTypeService = $repository->getContentTypeService();
42
43
        $groupCreate = $contentTypeService->newContentTypeGroupCreateStruct(
44
            'new-group'
45
        );
46
        /* END: Use Case */
47
48
        $this->assertInstanceOf(
49
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeGroupCreateStruct',
50
            $groupCreate
51
        );
52
53
        return $groupCreate;
54
    }
55
56
    /**
57
     * Test for the newContentTypeGroupCreateStruct() method.
58
     *
59
     * @see \eZ\Publish\API\Repository\ContentTypeService::newContentTypeGroupCreateStruct()
60
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testNewContentTypeGroupCreateStruct
61
     */
62
    public function testNewContentTypeGroupCreateStructValues($createStruct)
63
    {
64
        $this->assertPropertiesCorrect(
65
            [
66
                'identifier' => 'new-group',
67
                'creatorId' => null,
68
                'creationDate' => null,
69
                /* @todo uncomment when support for multilingual names and descriptions is added
70
                'mainLanguageCode' => null,
71
                */
72
            ],
73
            $createStruct
74
        );
75
    }
76
77
    /**
78
     * Test for the createContentTypeGroup() method.
79
     *
80
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeGroup()
81
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testNewContentTypeGroupCreateStruct
82
     * @group user
83
     */
84
    public function testCreateContentTypeGroup()
85
    {
86
        $repository = $this->getRepository();
87
88
        /* BEGIN: Use Case */
89
        $contentTypeService = $repository->getContentTypeService();
90
        $permissionResolver = $repository->getPermissionResolver();
91
92
        $groupCreate = $contentTypeService->newContentTypeGroupCreateStruct(
93
            'new-group'
94
        );
95
        $groupCreate->creatorId = $this->generateId('user', $permissionResolver->getCurrentUserReference()->getUserId());
96
        $groupCreate->creationDate = $this->createDateTime();
97
        /* @todo uncomment when support for multilingual names and descriptions is added
98
        $groupCreate->mainLanguageCode = 'ger-DE';
99
        $groupCreate->names = array( 'eng-GB' => 'A name.' );
100
        $groupCreate->descriptions = array( 'eng-GB' => 'A description.' );
101
        */
102
103
        $group = $contentTypeService->createContentTypeGroup($groupCreate);
104
        /* END: Use Case */
105
106
        $this->assertInstanceOf(
107
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeGroup',
108
            $group
109
        );
110
111
        return [
112
            'createStruct' => $groupCreate,
113
            'group' => $group,
114
        ];
115
    }
116
117
    /**
118
     * Test for the createContentTypeGroup() method.
119
     *
120
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeGroup()
121
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeGroup
122
     */
123
    public function testCreateContentTypeGroupStructValues(array $data)
124
    {
125
        $createStruct = $data['createStruct'];
126
        $group = $data['group'];
127
128
        $this->assertEquals(
129
            [
130
                'identifier' => $group->identifier,
131
                'creatorId' => $group->creatorId,
132
                'creationDate' => $group->creationDate->getTimestamp(),
133
            ],
134
            [
135
                'identifier' => $createStruct->identifier,
136
                'creatorId' => $createStruct->creatorId,
137
                'creationDate' => $createStruct->creationDate->getTimestamp(),
138
            ]
139
        );
140
        $this->assertNotNull(
141
            $group->id
142
        );
143
144
        return $data;
145
    }
146
147
    /**
148
     * Test for the createContentTypeGroup() method.
149
     *
150
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeGroup()
151
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeGroupStructValues
152
     */
153
    public function testCreateContentTypeGroupStructLanguageDependentValues(array $data)
154
    {
155
        $createStruct = $data['createStruct'];
156
        $group = $data['group'];
157
158
        $this->assertStructPropertiesCorrect(
159
            $createStruct,
160
            $group
161
            /* @todo uncomment when support for multilingual names and descriptions is added
162
            array( 'names', 'descriptions', 'mainLanguageCode' )
163
            */
164
        );
165
    }
166
167
    /**
168
     * Test for the createContentTypeGroup() method.
169
     *
170
     * @covers \eZ\Publish\API\Repository\ContentTypeService::createContentTypeGroup
171
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeGroup
172
     */
173
    public function testCreateContentTypeGroupThrowsInvalidArgumentException()
174
    {
175
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
176
        $this->expectExceptionMessage('Argument \'$contentTypeGroupCreateStruct\' is invalid: A group with the identifier \'Content\' already exists');
177
178
        $repository = $this->getRepository();
179
180
        /* BEGIN: Use Case */
181
        $contentTypeService = $repository->getContentTypeService();
182
183
        $groupCreate = $contentTypeService->newContentTypeGroupCreateStruct(
184
            'Content'
185
        );
186
187
        // Throws an Exception, since group "Content" already exists
188
        $contentTypeService->createContentTypeGroup($groupCreate);
189
        /* END: Use Case */
190
    }
191
192
    /**
193
     * Test for the loadContentTypeGroup() method.
194
     *
195
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeGroup()
196
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeGroup
197
     * @group user
198
     */
199
    public function testLoadContentTypeGroup()
200
    {
201
        $repository = $this->getRepository();
202
203
        $contentTypeGroupId = $this->generateId('typegroup', 2);
204
        /* BEGIN: Use Case */
205
        $contentTypeService = $repository->getContentTypeService();
206
207
        // Loads the "Users" group
208
        // $contentTypeGroupId is the ID of an existing content type group
209
        $loadedGroup = $contentTypeService->loadContentTypeGroup($contentTypeGroupId);
210
        /* END: Use Case */
211
212
        $this->assertInstanceOf(
213
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeGroup',
214
            $loadedGroup
215
        );
216
217
        return $loadedGroup;
218
    }
219
220
    /**
221
     * Test for the loadContentTypeGroup() method.
222
     *
223
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeGroup()
224
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroup
225
     */
226
    public function testLoadContentTypeGroupStructValues(ContentTypeGroup $group)
227
    {
228
        $this->assertPropertiesCorrect(
229
            [
230
                'id' => $this->generateId('typegroup', 2),
231
                'identifier' => 'Users',
232
                'creationDate' => $this->createDateTime(1031216941),
233
                'modificationDate' => $this->createDateTime(1033922113),
234
                'creatorId' => $this->generateId('user', 14),
235
                'modifierId' => $this->generateId('user', 14),
236
            ],
237
            $group
238
        );
239
    }
240
241
    /**
242
     * Test for the loadContentTypeGroup() method.
243
     *
244
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeGroup()
245
     */
246
    public function testLoadContentTypeGroupThrowsNotFoundException()
247
    {
248
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
249
250
        $repository = $this->getRepository();
251
252
        $contentTypeService = $repository->getContentTypeService();
253
        $loadedGroup = $contentTypeService->loadContentTypeGroup($this->generateId('typegroup', 2342));
0 ignored issues
show
Unused Code introduced by
$loadedGroup 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...
254
    }
255
256
    /**
257
     * Test for the loadContentTypeGroupByIdentifier() method.
258
     *
259
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeGroupByIdentifier()
260
     * @group user
261
     * @group field-type
262
     */
263
    public function testLoadContentTypeGroupByIdentifier()
264
    {
265
        $repository = $this->getRepository();
266
267
        /* BEGIN: Use Case */
268
        $contentTypeService = $repository->getContentTypeService();
269
270
        $loadedGroup = $contentTypeService->loadContentTypeGroupByIdentifier(
271
            'Media'
272
        );
273
        /* END: Use Case */
274
275
        $this->assertInstanceOf(
276
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeGroup',
277
            $loadedGroup
278
        );
279
280
        return $loadedGroup;
281
    }
282
283
    /**
284
     * Test for the loadContentTypeGroupByIdentifier() method.
285
     *
286
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeGroupByIdentifier()
287
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroupByIdentifier
288
     */
289
    public function testLoadContentTypeGroupByIdentifierStructValues(ContentTypeGroup $group)
290
    {
291
        $repository = $this->getRepository();
292
        $contentTypeService = $repository->getContentTypeService();
293
294
        $this->assertEquals(
295
            $contentTypeService->loadContentTypeGroup($this->generateId('typegroup', 3)),
296
            $group
297
        );
298
    }
299
300
    /**
301
     * Test for the loadContentTypeGroupByIdentifier() method.
302
     *
303
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeGroupByIdentifier()
304
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroupByIdentifier
305
     */
306
    public function testLoadContentTypeGroupByIdentifierThrowsNotFoundException()
307
    {
308
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
309
310
        $repository = $this->getRepository();
311
312
        /* BEGIN: Use Case */
313
        $contentTypeService = $repository->getContentTypeService();
314
315
        // Throws exception
316
        $loadedGroup = $contentTypeService->loadContentTypeGroupByIdentifier(
0 ignored issues
show
Unused Code introduced by
$loadedGroup 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...
317
            'not-exists'
318
        );
319
        /* END: Use Case */
320
    }
321
322
    /**
323
     * Test for the loadContentTypeGroups() method.
324
     *
325
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeGroups()
326
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeGroup
327
     */
328
    public function testLoadContentTypeGroups()
329
    {
330
        $repository = $this->getRepository();
331
332
        /* BEGIN: Use Case */
333
        $contentTypeService = $repository->getContentTypeService();
334
335
        // Loads an array with all content type groups
336
        $loadedGroups = $contentTypeService->loadContentTypeGroups();
337
        /* END: Use Case */
338
339
        $this->assertIsArray($loadedGroups
340
        );
341
342 View Code Duplication
        foreach ($loadedGroups as $loadedGroup) {
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...
343
            $this->assertStructPropertiesCorrect(
344
                $contentTypeService->loadContentTypeGroup($loadedGroup->id),
345
                $loadedGroup,
346
                [
347
                    'id',
348
                    'identifier',
349
                    'creationDate',
350
                    'modificationDate',
351
                    'creatorId',
352
                    'modifierId',
353
                ]
354
            );
355
        }
356
357
        return $loadedGroups;
358
    }
359
360
    /**
361
     * Test for the loadContentTypeGroups() method.
362
     *
363
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeGroups()
364
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroups
365
     */
366
    public function testLoadContentTypeGroupsIdentifiers($groups)
367
    {
368
        $this->assertCount(4, $groups);
369
370
        $expectedIdentifiers = [
371
            'Content' => true,
372
            'Users' => true,
373
            'Media' => true,
374
            'Setup' => true,
375
        ];
376
377
        $actualIdentifiers = [];
378
        foreach ($groups as $group) {
379
            $actualIdentifiers[$group->identifier] = true;
380
        }
381
382
        ksort($expectedIdentifiers);
383
        ksort($actualIdentifiers);
384
385
        $this->assertEquals(
386
            $expectedIdentifiers,
387
            $actualIdentifiers,
388
            'Identifier missmatch in loaded groups.'
389
        );
390
    }
391
392
    /**
393
     * Test for the newContentTypeGroupUpdateStruct() method.
394
     *
395
     * @see \eZ\Publish\API\Repository\ContentTypeService::newContentTypeGroupUpdateStruct()
396
     */
397
    public function testNewContentTypeGroupUpdateStruct()
398
    {
399
        $repository = $this->getRepository();
400
401
        /* BEGIN: Use Case */
402
        $contentTypeService = $repository->getContentTypeService();
403
404
        $groupUpdate = $contentTypeService->newContentTypeGroupUpdateStruct();
405
        /* END: Use Case */
406
407
        $this->assertInstanceOf(
408
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeGroupUpdateStruct',
409
            $groupUpdate
410
        );
411
    }
412
413
    /**
414
     * Test for the updateContentTypeGroup() method.
415
     *
416
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeGroup()
417
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeGroup
418
     */
419
    public function testUpdateContentTypeGroup()
420
    {
421
        $repository = $this->getRepository();
422
423
        $modifierId = $this->generateId('user', 42);
424
        /* BEGIN: Use Case */
425
        $contentTypeService = $repository->getContentTypeService();
426
427
        $group = $contentTypeService->loadContentTypeGroupByIdentifier('Setup');
428
429
        $groupUpdate = $contentTypeService->newContentTypeGroupUpdateStruct();
430
431
        $groupUpdate->identifier = 'Teardown';
432
        $groupUpdate->modifierId = $modifierId;
433
        $groupUpdate->modificationDate = $this->createDateTime();
434
        /* @todo uncomment when support for multilingual names and descriptions is added
435
        $groupUpdate->mainLanguageCode = 'eng-GB';
436
437
        $groupUpdate->names = array(
438
            'eng-GB' => 'A name',
439
            'eng-US' => 'A name',
440
        );
441
        $groupUpdate->descriptions = array(
442
            'eng-GB' => 'A description',
443
            'eng-US' => 'A description',
444
        );
445
        */
446
447
        $contentTypeService->updateContentTypeGroup($group, $groupUpdate);
448
        /* END: Use Case */
449
450
        $updatedGroup = $contentTypeService->loadContentTypeGroup($group->id);
451
452
        $this->assertInstanceOf(
453
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeGroupUpdateStruct',
454
            $groupUpdate
455
        );
456
457
        return [
458
            'originalGroup' => $group,
459
            'updateStruct' => $groupUpdate,
460
            'updatedGroup' => $updatedGroup,
461
        ];
462
    }
463
464
    /**
465
     * Test for the updateContentTypeGroup() method.
466
     *
467
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeGroup()
468
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeGroup
469
     */
470 View Code Duplication
    public function testUpdateContentTypeGroupStructValues(array $data)
471
    {
472
        $expectedValues = [
473
            'identifier' => $data['updateStruct']->identifier,
474
            'creationDate' => $data['originalGroup']->creationDate,
475
            'modificationDate' => $data['updateStruct']->modificationDate,
476
            'creatorId' => $data['originalGroup']->creatorId,
477
            'modifierId' => $data['updateStruct']->modifierId,
478
        ];
479
480
        $this->assertPropertiesCorrect($expectedValues, $data['updatedGroup']);
481
482
        return $data;
483
    }
484
485
    /**
486
     * Test for the updateContentTypeGroup() method.
487
     *
488
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeGroup()
489
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeGroupStructValues
490
     */
491 View Code Duplication
    public function testUpdateContentTypeGroupStructLanguageDependentValues(array $data)
492
    {
493
        $expectedValues = [
494
            'identifier' => $data['updateStruct']->identifier,
495
            'creationDate' => $data['originalGroup']->creationDate,
496
            'modificationDate' => $data['updateStruct']->modificationDate,
497
            'creatorId' => $data['originalGroup']->creatorId,
498
            'modifierId' => $data['updateStruct']->modifierId,
499
            /* @todo uncomment when support for multilingual names and descriptions is added
500
            'mainLanguageCode' => $data['updateStruct']->mainLanguageCode,
501
            'names' => $data['updateStruct']->names,
502
            'descriptions' => $data['updateStruct']->descriptions,
503
            */
504
        ];
505
506
        $this->assertPropertiesCorrect($expectedValues, $data['updatedGroup']);
507
    }
508
509
    /**
510
     * Test for the updateContentTypeGroup() method.
511
     *
512
     * @covers \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeGroup
513
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeGroup
514
     */
515
    public function testUpdateContentTypeGroupThrowsInvalidArgumentException()
516
    {
517
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
518
        $this->expectExceptionMessage('Argument \'$contentTypeGroupUpdateStruct->identifier\' is invalid: given identifier already exists');
519
520
        $repository = $this->getRepository();
521
522
        /* BEGIN: Use Case */
523
        $contentTypeService = $repository->getContentTypeService();
524
525
        $group = $contentTypeService->loadContentTypeGroupByIdentifier(
526
            'Media'
527
        );
528
529
        $groupUpdate = $contentTypeService->newContentTypeGroupUpdateStruct();
530
        $groupUpdate->identifier = 'Users';
531
532
        // Exception, because group with identifier "Users" exists
533
        $contentTypeService->updateContentTypeGroup($group, $groupUpdate);
534
        /* END: Use Case */
535
    }
536
537
    /**
538
     * Test for the deleteContentTypeGroup() method.
539
     *
540
     * @covers \eZ\Publish\API\Repository\ContentTypeService::deleteContentTypeGroup
541
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroup
542
     */
543
    public function testDeleteContentTypeGroup()
544
    {
545
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
546
547
        $repository = $this->getRepository();
548
549
        /* BEGIN: Use Case */
550
        $contentTypeService = $repository->getContentTypeService();
551
552
        $groupCreate = $contentTypeService->newContentTypeGroupCreateStruct(
553
            'new-group'
554
        );
555
        $contentTypeService->createContentTypeGroup($groupCreate);
556
557
        $group = $contentTypeService->loadContentTypeGroupByIdentifier('new-group');
558
559
        $contentTypeService->deleteContentTypeGroup($group);
560
        /* END: Use Case */
561
562
        // loadContentTypeGroup should throw NotFoundException
563
        $contentTypeService->loadContentTypeGroup($group->id);
564
565
        $this->fail('Content type group not deleted.');
566
    }
567
568
    /**
569
     * Test for the newContentTypeCreateStruct() method.
570
     *
571
     * @see \eZ\Publish\API\Repository\ContentTypeService::newContentTypeCreateStruct()
572
     * @group user
573
     * @group field-type
574
     */
575
    public function testNewContentTypeCreateStruct()
576
    {
577
        $repository = $this->getRepository();
578
579
        /* BEGIN: Use Case */
580
        $contentTypeService = $repository->getContentTypeService();
581
582
        $typeCreate = $contentTypeService->newContentTypeCreateStruct(
583
            'new-type'
584
        );
585
        /* END: Use Case */
586
587
        $this->assertInstanceOf(
588
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeCreateStruct',
589
            $typeCreate
590
        );
591
592
        return $typeCreate;
593
    }
594
595
    /**
596
     * Test for the newContentTypeCreateStruct() method.
597
     *
598
     * @see \eZ\Publish\API\Repository\ContentTypeService::newContentTypeCreateStruct()
599
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testNewContentTypeCreateStruct
600
     */
601
    public function testNewContentTypeCreateStructValues($createStruct)
602
    {
603
        $this->assertPropertiesCorrect(
604
            [
605
                'identifier' => 'new-type',
606
                'mainLanguageCode' => null,
607
                'remoteId' => null,
608
                'urlAliasSchema' => null,
609
                'nameSchema' => null,
610
                'isContainer' => false,
611
                'defaultSortField' => Location::SORT_FIELD_PUBLISHED,
612
                'defaultSortOrder' => Location::SORT_ORDER_DESC,
613
                'defaultAlwaysAvailable' => true,
614
                'names' => null,
615
                'descriptions' => null,
616
                'creatorId' => null,
617
                'creationDate' => null,
618
            ],
619
            $createStruct
620
        );
621
    }
622
623
    /**
624
     * Test for the newFieldDefinitionCreateStruct() method.
625
     *
626
     * @see \eZ\Publish\API\Repository\ContentTypeService::newFieldDefinitionCreateStruct()
627
     * @group user
628
     * @group field-type
629
     */
630
    public function testNewFieldDefinitionCreateStruct()
631
    {
632
        $repository = $this->getRepository();
633
634
        /* BEGIN: Use Case */
635
        $contentTypeService = $repository->getContentTypeService();
636
637
        $fieldDefinitionCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
638
        /* END: Use Case */
639
640
        $this->assertInstanceOf(
641
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\FieldDefinitionCreateStruct',
642
            $fieldDefinitionCreate
643
        );
644
645
        return $fieldDefinitionCreate;
646
    }
647
648
    /**
649
     * Test for the newFieldDefinitionCreateStruct() method.
650
     *
651
     * @see \eZ\Publish\API\Repository\ContentTypeService::newFieldDefinitionCreateStruct()
652
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testNewFieldDefinitionCreateStruct
653
     */
654
    public function testNewFieldDefinitionCreateStructValues($createStruct)
655
    {
656
        $this->assertPropertiesCorrect(
657
            [
658
                'fieldTypeIdentifier' => 'ezstring',
659
                'identifier' => 'title',
660
                'names' => null,
661
                'descriptions' => null,
662
                'fieldGroup' => null,
663
                'position' => null,
664
                'isTranslatable' => null,
665
                'isRequired' => null,
666
                'isInfoCollector' => null,
667
                'validatorConfiguration' => null,
668
                'fieldSettings' => null,
669
                'defaultValue' => null,
670
                'isSearchable' => null,
671
            ],
672
            $createStruct
673
        );
674
    }
675
676
    /**
677
     * Test for the deleteContentTypeGroup() method.
678
     *
679
     * @see \eZ\Publish\API\Repository\ContentTypeService::deleteContentTypeGroup()
680
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testDeleteContentTypeGroup
681
     */
682
    public function testDeleteContentTypeGroupThrowsInvalidArgumentException()
683
    {
684
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
685
686
        $repository = $this->getRepository();
687
688
        /* BEGIN: Use Case */
689
        $contentTypeService = $repository->getContentTypeService();
690
691
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
692
693
        // Throws exception, since group contains types
694
        $contentTypeService->deleteContentTypeGroup($contentGroup);
695
        /* END: Use Case */
696
    }
697
698
    /**
699
     * Test for the createContentType() method.
700
     *
701
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentType()
702
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testNewContentTypeCreateStruct
703
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testNewFieldDefinitionCreateStruct
704
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroupByIdentifier
705
     * @group user
706
     * @group field-type
707
     */
708
    public function testCreateContentType()
709
    {
710
        $repository = $this->getRepository();
711
712
        /* BEGIN: Use Case */
713
        $contentTypeService = $repository->getContentTypeService();
714
        $permissionResolver = $repository->getPermissionResolver();
715
716
        $typeCreate = $contentTypeService->newContentTypeCreateStruct('blog-post');
717
        $typeCreate->mainLanguageCode = 'eng-GB';
718
        $typeCreate->remoteId = '384b94a1bd6bc06826410e284dd9684887bf56fc';
719
        $typeCreate->urlAliasSchema = 'url|scheme';
720
        $typeCreate->nameSchema = 'name|scheme';
721
        $typeCreate->names = [
722
            'eng-GB' => 'Blog post',
723
            'ger-DE' => 'Blog-Eintrag',
724
        ];
725
        $typeCreate->descriptions = [
726
            'eng-GB' => 'A blog post',
727
            'ger-DE' => 'Ein Blog-Eintrag',
728
        ];
729
        $typeCreate->creatorId = $this->generateId('user', $permissionResolver->getCurrentUserReference()->getUserId());
730
        $typeCreate->creationDate = $this->createDateTime();
731
732
        $titleFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
733
        $titleFieldCreate->names = [
734
            'eng-GB' => 'Title',
735
            'ger-DE' => 'Titel',
736
        ];
737
        $titleFieldCreate->descriptions = [
738
            'eng-GB' => 'Title of the blog post',
739
            'ger-DE' => 'Titel des Blog-Eintrages',
740
        ];
741
        $titleFieldCreate->fieldGroup = 'blog-content';
742
        $titleFieldCreate->position = 1;
743
        $titleFieldCreate->isTranslatable = true;
744
        $titleFieldCreate->isRequired = true;
745
        $titleFieldCreate->isInfoCollector = false;
746
        $titleFieldCreate->validatorConfiguration = [
747
            'StringLengthValidator' => [
748
                'minStringLength' => 0,
749
                'maxStringLength' => 0,
750
            ],
751
        ];
752
        $titleFieldCreate->fieldSettings = [];
753
        $titleFieldCreate->isSearchable = true;
754
        $titleFieldCreate->defaultValue = 'default title';
755
756
        $typeCreate->addFieldDefinition($titleFieldCreate);
757
758
        $bodyFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('body', 'ezstring');
759
        $bodyFieldCreate->names = [
760
            'eng-GB' => 'Body',
761
            'ger-DE' => 'Textkörper',
762
        ];
763
        $bodyFieldCreate->descriptions = [
764
            'eng-GB' => 'Body of the blog post',
765
            'ger-DE' => 'Textkörper des Blog-Eintrages',
766
        ];
767
        $bodyFieldCreate->fieldGroup = 'blog-content';
768
        $bodyFieldCreate->position = 2;
769
        $bodyFieldCreate->isTranslatable = true;
770
        $bodyFieldCreate->isRequired = true;
771
        $bodyFieldCreate->isInfoCollector = false;
772
        $bodyFieldCreate->validatorConfiguration = [
773
            'StringLengthValidator' => [
774
                'minStringLength' => 0,
775
                'maxStringLength' => 0,
776
            ],
777
        ];
778
        $bodyFieldCreate->fieldSettings = [];
779
        $bodyFieldCreate->isSearchable = true;
780
        $bodyFieldCreate->defaultValue = 'default content';
781
782
        $typeCreate->addFieldDefinition($bodyFieldCreate);
783
784
        $groups = [
785
            $contentTypeService->loadContentTypeGroupByIdentifier('Media'),
786
            $contentTypeService->loadContentTypeGroupByIdentifier('Setup'),
787
        ];
788
789
        $contentTypeDraft = $contentTypeService->createContentType(
790
            $typeCreate,
791
            $groups
792
        );
793
        /* END: Use Case */
794
795
        $this->assertInstanceOf(
796
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType',
797
            $contentTypeDraft
798
        );
799
800
        return [
801
            'typeCreate' => $typeCreate,
802
            'contentType' => $contentTypeDraft,
803
            'groups' => $groups,
804
        ];
805
    }
806
807
    /**
808
     * Test for the createContentType() method struct values.
809
     *
810
     * @covers \eZ\Publish\API\Repository\ContentTypeService::createContentType
811
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
812
     *
813
     * @param array $data
814
     */
815
    public function testCreateContentTypeStructValues(array $data)
816
    {
817
        $typeCreate = $data['typeCreate'];
818
        $contentType = $data['contentType'];
819
        $groups = $data['groups'];
820
821
        foreach ($typeCreate as $propertyName => $propertyValue) {
822
            switch ($propertyName) {
823
                case 'fieldDefinitions':
824
                    $this->assertFieldDefinitionsCorrect(
825
                        $typeCreate->fieldDefinitions,
826
                        $contentType->fieldDefinitions->toArray()
827
                    );
828
                    break;
829
830
                case 'creationDate':
831
                case 'modificationDate':
832
                    $this->assertEquals(
833
                        $typeCreate->$propertyName->getTimestamp(),
834
                        $contentType->$propertyName->getTimestamp()
835
                    );
836
                    break;
837
838
                default:
839
                    $this->assertEquals(
840
                        $typeCreate->$propertyName,
841
                        $contentType->$propertyName,
842
                        "Did not assert that property '${propertyName}' is equal on struct and resulting value object"
843
                    );
844
                    break;
845
            }
846
        }
847
848
        $this->assertContentTypeGroupsCorrect(
849
            $groups,
850
            $contentType->contentTypeGroups
851
        );
852
853
        $this->assertNotNull(
854
            $contentType->id
855
        );
856
    }
857
858
    /**
859
     * Asserts field definition creation.
860
     *
861
     * Asserts that all field definitions defined through created structs in
862
     * $expectedDefinitionCreates have been correctly created in
863
     * $actualDefinitions.
864
     *
865
     * @param \eZ\Publish\API\Repository\Values\FieldDefinitionCreateStruct[] $expectedDefinitionCreates
866
     * @param \eZ\Publish\API\Repository\Values\FieldDefinition[] $actualDefinitions
867
     */
868
    protected function assertFieldDefinitionsCorrect(array $expectedDefinitionCreates, array $actualDefinitions)
869
    {
870
        $this->assertEquals(
871
            count($expectedDefinitionCreates),
872
            count($actualDefinitions),
873
            'Count of field definition creates did not match count of field definitions.'
874
        );
875
876
        $sorter = function ($a, $b) {
877
            return strcmp($a->identifier, $b->identifier);
878
        };
879
880
        usort($expectedDefinitionCreates, $sorter);
881
        usort($actualDefinitions, $sorter);
882
883
        foreach ($expectedDefinitionCreates as $key => $expectedCreate) {
884
            $this->assertFieldDefinitionsEqual(
885
                $expectedCreate,
886
                $actualDefinitions[$key]
887
            );
888
        }
889
    }
890
891
    /**
892
     * Asserts that a field definition has been correctly created.
893
     *
894
     * Asserts that the given $actualDefinition is correctly created from the
895
     * create struct in $expectedCreate.
896
     *
897
     * @param \eZ\Publish\API\Repository\Values\FieldDefinitionCreateStruct $expectedDefinitionCreate
0 ignored issues
show
Bug introduced by
There is no parameter named $expectedDefinitionCreate. 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...
898
     * @param \eZ\Publish\API\Repository\Values\FieldDefinition $actualDefinition
899
     */
900
    protected function assertFieldDefinitionsEqual($expectedCreate, $actualDefinition)
901
    {
902
        foreach ($expectedCreate as $propertyName => $propertyValue) {
903
            $this->assertEquals(
904
                $expectedCreate->$propertyName,
905
                $actualDefinition->$propertyName
906
            );
907
        }
908
    }
909
910
    /**
911
     * Asserts that two sets of ContentTypeGroups are equal.
912
     *
913
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup[] $expectedGroups
914
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup[] $actualGroups
915
     */
916
    protected function assertContentTypeGroupsCorrect($expectedGroups, $actualGroups)
917
    {
918
        $sorter = function ($a, $b) {
919
            return strcmp($a->id, $b->id);
920
        };
921
922
        usort($expectedGroups, $sorter);
923
        usort($actualGroups, $sorter);
924
925 View Code Duplication
        foreach ($expectedGroups as $key => $expectedGroup) {
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...
926
            $this->assertStructPropertiesCorrect(
927
                $expectedGroup,
928
                $actualGroups[$key],
929
                [
930
                    'id',
931
                    'identifier',
932
                    'creationDate',
933
                    'modificationDate',
934
                    'creatorId',
935
                    'modifierId',
936
                ]
937
            );
938
        }
939
    }
940
941
    /**
942
     * Test for the createContentType() method.
943
     *
944
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentType()
945
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
946
     */
947 View Code Duplication
    public function testCreateContentTypeThrowsInvalidArgumentExceptionDuplicateIdentifier()
948
    {
949
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
950
        $this->expectExceptionMessage('Argument \'$contentTypeCreateStruct\' is invalid: Another Content Type with identifier \'folder\' exists');
951
952
        $repository = $this->getRepository();
953
954
        /* BEGIN: Use Case */
955
        $contentTypeService = $repository->getContentTypeService();
956
957
        $typeCreate = $contentTypeService->newContentTypeCreateStruct('folder');
958
        $typeCreate->mainLanguageCode = 'eng-GB';
959
        $typeCreate->names = ['eng-GB' => 'Article'];
960
961
        $firstFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
962
        $typeCreate->addFieldDefinition($firstFieldCreate);
963
964
        $groups = [
965
            $contentTypeService->loadContentTypeGroupByIdentifier('Media'),
966
            $contentTypeService->loadContentTypeGroupByIdentifier('Setup'),
967
        ];
968
969
        // Throws exception, since type "folder" exists
970
        $contentTypeService->createContentType($typeCreate, $groups);
971
        /* END: Use Case */
972
    }
973
974
    /**
975
     * Test for the createContentType() method trying to create Content Type with already existing
976
     * remoteId.
977
     *
978
     * @covers \eZ\Publish\API\Repository\ContentTypeService::createContentType()
979
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
980
     */
981 View Code Duplication
    public function testCreateContentTypeThrowsInvalidArgumentExceptionDuplicateRemoteId()
982
    {
983
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
984
        $this->expectExceptionMessage('Another Content Type with remoteId \'a3d405b81be900468eb153d774f4f0d2\' exists');
985
986
        $repository = $this->getRepository();
987
988
        /* BEGIN: Use Case */
989
        $contentTypeService = $repository->getContentTypeService();
990
991
        $typeCreate = $contentTypeService->newContentTypeCreateStruct('news-article');
992
        $typeCreate->remoteId = 'a3d405b81be900468eb153d774f4f0d2';
993
        $typeCreate->mainLanguageCode = 'eng-GB';
994
        $typeCreate->names = ['eng-GB' => 'Article'];
995
996
        $firstFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
997
        $typeCreate->addFieldDefinition($firstFieldCreate);
998
999
        $groups = [
1000
            $contentTypeService->loadContentTypeGroupByIdentifier('Media'),
1001
            $contentTypeService->loadContentTypeGroupByIdentifier('Setup'),
1002
        ];
1003
1004
        // Throws exception, since "folder" type has this remote ID
1005
        $contentTypeService->createContentType($typeCreate, $groups);
1006
        /* END: Use Case */
1007
    }
1008
1009
    /**
1010
     * Test for the createContentType() method creating content with duplicate field identifiers.
1011
     *
1012
     * @covers \eZ\Publish\API\Repository\ContentTypeService::createContentType
1013
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
1014
     */
1015
    public function testCreateContentTypeThrowsInvalidArgumentExceptionDuplicateFieldIdentifier()
1016
    {
1017
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1018
        $this->expectExceptionMessage('Argument \'$contentTypeCreateStruct\' is invalid: The argument contains duplicate Field definition identifier \'title\'');
1019
1020
        $repository = $this->getRepository();
1021
1022
        /* BEGIN: Use Case */
1023
        $contentTypeService = $repository->getContentTypeService();
1024
1025
        $typeCreate = $contentTypeService->newContentTypeCreateStruct('blog-post');
1026
        $typeCreate->mainLanguageCode = 'eng-GB';
1027
        $typeCreate->names = ['eng-GB' => 'Blog post'];
1028
1029
        $firstFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
1030
        $typeCreate->addFieldDefinition($firstFieldCreate);
1031
1032
        $secondFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
1033
        $typeCreate->addFieldDefinition($secondFieldCreate);
1034
1035
        $groups = [
1036
            $contentTypeService->loadContentTypeGroupByIdentifier('Media'),
1037
            $contentTypeService->loadContentTypeGroupByIdentifier('Setup'),
1038
        ];
1039
1040
        // Throws exception, due to duplicate "title" field
1041
        $contentTypeService->createContentType($typeCreate, $groups);
1042
        /* END: Use Case */
1043
    }
1044
1045
    /**
1046
     * Test for the createContentTypeGroup() method trying to create a content type with already
1047
     * existing identifier.
1048
     *
1049
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
1050
     * @covers \eZ\Publish\Core\Repository\ContentTypeService::createContentType
1051
     */
1052
    public function testCreateContentTypeThrowsInvalidArgumentExceptionDuplicateContentTypeIdentifier()
1053
    {
1054
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1055
        $this->expectExceptionMessage('Another Content Type with identifier \'blog-post\' exists');
1056
1057
        $repository = $this->getRepository();
1058
        $contentTypeService = $repository->getContentTypeService();
1059
1060
        // create published content type with identifier "blog-post"
1061
        $contentTypeDraft = $this->createContentTypeDraft();
1062
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1063
1064
        $typeCreateStruct = $contentTypeService->newContentTypeCreateStruct('blog-post');
1065
        $typeCreateStruct->remoteId = 'other-remote-id';
1066
        $typeCreateStruct->creatorId = $repository->getPermissionResolver()->getCurrentUserReference()->getUserId();
1067
        $typeCreateStruct->creationDate = new \DateTime();
1068
        $typeCreateStruct->mainLanguageCode = 'eng-US';
1069
        $typeCreateStruct->names = ['eng-US' => 'A name.'];
1070
        $typeCreateStruct->descriptions = ['eng-US' => 'A description.'];
1071
1072
        $fieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('test', 'eztext');
1073
        $typeCreateStruct->addFieldDefinition($fieldCreate);
1074
1075
        // Throws an exception because content type with identifier "blog-post" already exists
1076
        $contentTypeService->createContentType(
1077
            $typeCreateStruct,
1078
            [
1079
                $contentTypeService->loadContentTypeGroupByIdentifier('Content'),
1080
            ]
1081
        );
1082
    }
1083
1084
    /**
1085
     * Test for the createContentType() method.
1086
     *
1087
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentType()
1088
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
1089
     */
1090
    public function testCreateContentTypeThrowsContentTypeFieldDefinitionValidationException()
1091
    {
1092
        $repository = $this->getRepository();
1093
1094
        /* BEGIN: Use Case */
1095
        $contentTypeService = $repository->getContentTypeService();
1096
1097
        $typeCreate = $contentTypeService->newContentTypeCreateStruct('blog-post');
1098
        $typeCreate->mainLanguageCode = 'eng-GB';
1099
        $typeCreate->names = ['eng-GB' => 'Blog post'];
1100
1101
        $fieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('temperature', 'ezinteger');
1102
        $fieldCreate->isSearchable = true;
1103
        $fieldCreate->validatorConfiguration = [
1104
            'IntegerValueValidator' => [
1105
                'minIntegerValue' => 'forty two point one',
1106
                'maxIntegerValue' => 75,
1107
            ],
1108
        ];
1109
        $typeCreate->addFieldDefinition($fieldCreate);
1110
1111
        $groups = [
1112
            $contentTypeService->loadContentTypeGroupByIdentifier('Media'),
1113
            $contentTypeService->loadContentTypeGroupByIdentifier('Setup'),
1114
        ];
1115
1116
        try {
1117
            // Throws validation exception, because field's validator configuration is invalid
1118
            $contentType = $contentTypeService->createContentType($typeCreate, $groups);
0 ignored issues
show
Unused Code introduced by
$contentType is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1119
        } catch (ContentTypeFieldDefinitionValidationException $e) {
1120
            $validationErrors = $e->getFieldErrors();
1121
        }
1122
        /* END: Use Case */
1123
1124
        /* @var $validationErrors */
1125
        $this->assertTrue(isset($validationErrors));
1126
        $this->assertIsArray($validationErrors);
0 ignored issues
show
Bug introduced by
The variable $validationErrors does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1127
        $this->assertCount(1, $validationErrors);
1128
        $this->assertArrayHasKey('temperature', $validationErrors);
1129
        $this->assertIsArray($validationErrors['temperature']);
1130
        $this->assertCount(1, $validationErrors['temperature']);
1131
        $this->assertInstanceOf('eZ\\Publish\\Core\\FieldType\\ValidationError', $validationErrors['temperature'][0]);
1132
1133
        $this->assertEquals(
1134
            new Message(
1135
                "Validator parameter '%parameter%' value must be of integer type",
1136
                ['%parameter%' => 'minIntegerValue']
1137
            ),
1138
            $validationErrors['temperature'][0]->getTranslatableMessage()
1139
        );
1140
    }
1141
1142
    /**
1143
     * Test for the createContentTypeGroup() method called with no groups.
1144
     *
1145
     * @depends testCreateContentType
1146
     * @covers \eZ\Publish\Core\Repository\ContentTypeService::createContentTypeGroup
1147
     */
1148
    public function testCreateContentTypeThrowsInvalidArgumentExceptionGroupsEmpty()
1149
    {
1150
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1151
        $this->expectExceptionMessage('Argument \'$contentTypeGroups\' is invalid: The argument must contain at least one Content Type group');
1152
1153
        $repository = $this->getRepository();
1154
1155
        $contentTypeService = $repository->getContentTypeService();
1156
1157
        $contentTypeCreateStruct = $contentTypeService->newContentTypeCreateStruct(
1158
            'new-type'
1159
        );
1160
        $contentTypeCreateStruct->mainLanguageCode = 'eng-GB';
1161
        $contentTypeCreateStruct->names = ['eng-GB' => 'Test type'];
1162
1163
        // Thrown an exception because array of content type groups is empty
1164
        $contentTypeService->createContentType($contentTypeCreateStruct, []);
1165
    }
1166
1167
    /**
1168
     * Test for the newContentTypeUpdateStruct() method.
1169
     *
1170
     * @see \eZ\Publish\API\Repository\ContentTypeService::newContentTypeUpdateStruct()
1171
     */
1172
    public function testNewContentTypeUpdateStruct()
1173
    {
1174
        $repository = $this->getRepository();
1175
1176
        /* BEGIN: Use Case */
1177
        $contentTypeService = $repository->getContentTypeService();
1178
1179
        $typeUpdate = $contentTypeService->newContentTypeUpdateStruct();
1180
        /* END: Use Case */
1181
1182
        $this->assertInstanceOf(
1183
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeUpdateStruct',
1184
            $typeUpdate
1185
        );
1186
1187
        return $typeUpdate;
1188
    }
1189
1190
    /**
1191
     * Test for the newContentTypeUpdateStruct() method.
1192
     *
1193
     * @see \eZ\Publish\API\Repository\ContentTypeService::newContentTypeUpdateStruct()
1194
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testNewContentTypeUpdateStruct
1195
     */
1196
    public function testNewContentTypeUpdateStructValues($typeUpdate)
1197
    {
1198
        foreach ($typeUpdate as $propertyName => $propertyValue) {
1199
            $this->assertNull(
1200
                $propertyValue,
1201
                "Property '$propertyName' is not null."
1202
            );
1203
        }
1204
    }
1205
1206
    /**
1207
     * Test for the loadContentTypeDraft() method.
1208
     *
1209
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeDraft()
1210
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
1211
     */
1212
    public function testLoadContentTypeDraft()
1213
    {
1214
        $repository = $this->getRepository();
1215
        $contentTypeService = $repository->getContentTypeService();
1216
1217
        /* BEGIN: Use Case */
1218
        $contentTypeDraft = $this->createContentTypeDraft();
1219
1220
        $contentTypeDraftReloaded = $contentTypeService->loadContentTypeDraft(
1221
            $contentTypeDraft->id
1222
        );
1223
        /* END: Use Case */
1224
1225
        $this->assertEquals(
1226
            $contentTypeDraft,
1227
            $contentTypeDraftReloaded
1228
        );
1229
    }
1230
1231
    /**
1232
     * Test for the loadContentTypeDraft() method.
1233
     *
1234
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeDraft()
1235
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeDraft
1236
     */
1237
    public function testLoadContentTypeDraftThrowsNotFoundException()
1238
    {
1239
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1240
1241
        $repository = $this->getRepository();
1242
1243
        $nonExistingContentTypeId = $this->generateId('type', 2342);
1244
        /* BEGIN: Use Case */
1245
        $contentTypeService = $repository->getContentTypeService();
1246
1247
        // Throws exception, since 2342 does not exist
1248
        $contentTypeDraft = $contentTypeService->loadContentTypeDraft($nonExistingContentTypeId);
0 ignored issues
show
Unused Code introduced by
$contentTypeDraft 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...
1249
        /* END: Use Case */
1250
    }
1251
1252
    /**
1253
     * Test for the loadContentTypeDraft() method.
1254
     *
1255
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeDraft()
1256
     */
1257
    public function testLoadContentTypeDraftThrowsNotFoundExceptionIfDiffrentOwner()
1258
    {
1259
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
1260
1261
        $repository = $this->getRepository();
1262
        $permissionResolver = $repository->getPermissionResolver();
1263
        $contentTypeService = $repository->getContentTypeService();
1264
1265
        $draft = $this->createContentTypeDraft();
1266
1267
        $anotherUser = $this->createUserVersion1('anotherUser');
1268
        $permissionResolver->setCurrentUserReference($anotherUser);
1269
1270
        $contentTypeDraft = $contentTypeService->loadContentTypeDraft($draft->id);
0 ignored issues
show
Unused Code introduced by
$contentTypeDraft 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...
1271
    }
1272
1273
    /**
1274
     * Test for the loadContentTypeDraft() method.
1275
     *
1276
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeDraft()
1277
     */
1278
    public function testCanLoadContentTypeDraftEvenIfDiffrentOwner()
1279
    {
1280
        $repository = $this->getRepository();
1281
        $userService = $repository->getUserService();
0 ignored issues
show
Unused Code introduced by
$userService 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...
1282
        $permissionResolver = $repository->getPermissionResolver();
1283
        $contentTypeService = $repository->getContentTypeService();
1284
1285
        $draft = $this->createContentTypeDraft();
1286
1287
        $anotherUser = $this->createUserVersion1('anotherUser');
1288
        $permissionResolver->setCurrentUserReference($anotherUser);
1289
1290
        $loadedDraft = $contentTypeService->loadContentTypeDraft($draft->id, true);
1291
1292
        $this->assertSame((int)$loadedDraft->id, (int)$draft->id);
1293
    }
1294
1295
    /**
1296
     * Test for the updateContentTypeDraft() method.
1297
     *
1298
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeDraft()
1299
     */
1300
    public function testUpdateContentTypeDraft()
1301
    {
1302
        $repository = $this->getRepository();
1303
        $contentTypeService = $repository->getContentTypeService();
1304
1305
        $modifierId = $this->generateId('user', 14);
1306
        /* BEGIN: Use Case */
1307
        $contentTypeDraft = $this->createContentTypeDraft();
1308
1309
        $typeUpdate = $contentTypeService->newContentTypeUpdateStruct();
1310
        $typeUpdate->identifier = 'news-article';
1311
        $typeUpdate->remoteId = '4cf35f5166fd31bf0cda859dc837e095daee9833';
1312
        $typeUpdate->urlAliasSchema = 'url@alias|scheme';
1313
        $typeUpdate->nameSchema = '@name@scheme@';
1314
        $typeUpdate->isContainer = true;
1315
        $typeUpdate->mainLanguageCode = 'eng-US';
1316
        $typeUpdate->defaultAlwaysAvailable = false;
1317
        $typeUpdate->modifierId = $modifierId;
1318
        $typeUpdate->modificationDate = $this->createDateTime();
1319
        $typeUpdate->names = [
1320
            'eng-GB' => 'News article',
1321
            'ger-DE' => 'Nachrichten-Artikel',
1322
        ];
1323
        $typeUpdate->descriptions = [
1324
            'eng-GB' => 'A news article',
1325
            'ger-DE' => 'Ein Nachrichten-Artikel',
1326
        ];
1327
1328
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $typeUpdate);
1329
        /* END: Use Case */
1330
1331
        $updatedType = $contentTypeService->loadContentTypeDraft(
1332
            $contentTypeDraft->id
1333
        );
1334
1335
        $this->assertInstanceOf(
1336
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeDraft',
1337
            $updatedType
1338
        );
1339
1340
        return [
1341
            'originalType' => $contentTypeDraft,
1342
            'updateStruct' => $typeUpdate,
1343
            'updatedType' => $updatedType,
1344
        ];
1345
    }
1346
1347
    /**
1348
     * Test for the updateContentTypeDraft() method.
1349
     *
1350
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeDraft()
1351
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeDraft
1352
     */
1353
    public function testUpdateContentTypeDraftStructValues($data)
1354
    {
1355
        $originalType = $data['originalType'];
1356
        $updateStruct = $data['updateStruct'];
1357
        $updatedType = $data['updatedType'];
1358
1359
        $expectedValues = [
1360
            'id' => $originalType->id,
1361
            'names' => $updateStruct->names,
1362
            'descriptions' => $updateStruct->descriptions,
1363
            'identifier' => $updateStruct->identifier,
1364
            'creationDate' => $originalType->creationDate,
1365
            'modificationDate' => $updateStruct->modificationDate,
1366
            'creatorId' => $originalType->creatorId,
1367
            'modifierId' => $updateStruct->modifierId,
1368
            'urlAliasSchema' => $updateStruct->urlAliasSchema,
1369
            'nameSchema' => $updateStruct->nameSchema,
1370
            'isContainer' => $updateStruct->isContainer,
1371
            'mainLanguageCode' => $updateStruct->mainLanguageCode,
1372
            'contentTypeGroups' => $originalType->contentTypeGroups,
1373
            'fieldDefinitions' => $originalType->fieldDefinitions,
1374
        ];
1375
1376
        $this->assertPropertiesCorrect(
1377
            $expectedValues,
1378
            $updatedType
1379
        );
1380
1381
        foreach ($originalType->fieldDefinitions as $index => $expectedFieldDefinition) {
1382
            $actualFieldDefinition = $updatedType->fieldDefinitions[$index];
1383
            $this->assertInstanceOf(
1384
                FieldDefinition::class,
1385
                $actualFieldDefinition
1386
            );
1387
            $this->assertEquals($expectedFieldDefinition, $actualFieldDefinition);
1388
        }
1389
    }
1390
1391
    /**
1392
     * @covers \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeDraft
1393
     *
1394
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1395
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1396
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1397
     */
1398
    public function testUpdateContentTypeDraftWithNewTranslation()
1399
    {
1400
        $repository = $this->getRepository();
1401
        $contentTypeService = $repository->getContentTypeService();
1402
1403
        $contentTypeDraft = $this->createContentTypeDraft();
1404
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1405
1406
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
1407
        // sanity check
1408
        self::assertEquals(
1409
            ['eng-US', 'ger-DE'],
1410
            array_keys($contentType->getNames())
1411
        );
1412
1413
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1414
        $updateStruct = $contentTypeService->newContentTypeUpdateStruct();
1415
        $updateStruct->names = [
1416
            'eng-GB' => 'BrE blog post',
1417
        ];
1418
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $updateStruct);
1419
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1420
1421
        self::assertEquals(
1422
            [
1423
                'eng-US' => 'Blog post',
1424
                'ger-DE' => 'Blog-Eintrag',
1425
                'eng-GB' => 'BrE blog post',
1426
            ],
1427
            $contentTypeService->loadContentType($contentType->id)->getNames()
1428
        );
1429
    }
1430
1431
    /**
1432
     * Test for the updateContentTypeDraft() method.
1433
     *
1434
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeDraft()
1435
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeDraft
1436
     */
1437 View Code Duplication
    public function testUpdateContentTypeDraftThrowsInvalidArgumentExceptionDuplicateIdentifier()
1438
    {
1439
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1440
1441
        $repository = $this->getRepository();
1442
        $contentTypeService = $repository->getContentTypeService();
1443
1444
        /* BEGIN: Use Case */
1445
        $contentTypeDraft = $this->createContentTypeDraft();
1446
1447
        $typeUpdate = $contentTypeService->newContentTypeUpdateStruct();
1448
        $typeUpdate->identifier = 'folder';
1449
1450
        // Throws exception, since type "folder" already exists
1451
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $typeUpdate);
1452
        /* END: Use Case */
1453
    }
1454
1455
    /**
1456
     * Test for the updateContentTypeDraft() method.
1457
     *
1458
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeDraft()
1459
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeDraft
1460
     */
1461 View Code Duplication
    public function testUpdateContentTypeDraftThrowsInvalidArgumentExceptionDuplicateRemoteId()
1462
    {
1463
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1464
1465
        $repository = $this->getRepository();
1466
        $contentTypeService = $repository->getContentTypeService();
1467
1468
        /* BEGIN: Use Case */
1469
        $contentTypeDraft = $this->createContentTypeDraft();
1470
1471
        $typeUpdate = $contentTypeService->newContentTypeUpdateStruct();
1472
        $typeUpdate->remoteId = 'a3d405b81be900468eb153d774f4f0d2';
1473
1474
        // Throws exception, since remote ID of type "folder" is used
1475
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $typeUpdate);
1476
        /* END: Use Case */
1477
    }
1478
1479
    /**
1480
     * Test for the updateContentTypeDraft() method.
1481
     *
1482
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeDraft
1483
     * @covers \eZ\Publish\Core\Repository\ContentTypeService::updateContentTypeDraft
1484
     */
1485
    public function testUpdateContentTypeDraftThrowsInvalidArgumentExceptionNoDraftForAuthenticatedUser()
1486
    {
1487
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1488
        $this->expectExceptionMessage('Argument \'$contentTypeDraft\' is invalid: There is no Content Type draft assigned to the authenticated user');
1489
1490
        $repository = $this->getRepository();
1491
        $contentTypeService = $repository->getContentTypeService();
1492
        $roleService = $repository->getRoleService();
1493
1494
        $contentTypeDraft = $this->createContentTypeDraft();
1495
        $typeUpdate = $contentTypeService->newContentTypeUpdateStruct();
1496
1497
        // create Role allowing Content Type updates
1498
        $roleCreateStruct = $roleService->newRoleCreateStruct('ContentTypeUpdaters');
1499
        $policyCreateStruct = $roleService->newPolicyCreateStruct('class', 'update');
1500
        $roleDraft = $roleService->createRole($roleCreateStruct);
1501
        $roleService->addPolicyByRoleDraft($roleDraft, $policyCreateStruct);
1502
        $roleService->publishRoleDraft($roleDraft);
1503
1504
        $user = $this->createUserVersion1();
1505
        $roleService->assignRoleToUser(
1506
            $roleService->loadRoleByIdentifier('ContentTypeUpdaters'),
1507
            $user
1508
        );
1509
        $repository->getPermissionResolver()->setCurrentUserReference($user);
1510
1511
        // Throws exception, since draft belongs to another user
1512
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $typeUpdate);
1513
    }
1514
1515
    /**
1516
     * Test for the addFieldDefinition() method.
1517
     *
1518
     * @return array
1519
     *
1520
     * @see \eZ\Publish\API\Repository\ContentTypeService::addFieldDefinition()
1521
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
1522
     */
1523
    public function testAddFieldDefinition()
1524
    {
1525
        $repository = $this->getRepository();
1526
        $contentTypeService = $repository->getContentTypeService();
1527
1528
        /* BEGIN: Use Case */
1529
        $contentTypeDraft = $this->createContentTypeDraft();
1530
1531
        $fieldDefCreate = $contentTypeService->newFieldDefinitionCreateStruct('tags', 'ezstring');
1532
        $fieldDefCreate->names = [
1533
            'eng-GB' => 'Tags',
1534
            'ger-DE' => 'Schlagworte',
1535
        ];
1536
        $fieldDefCreate->descriptions = [
1537
            'eng-GB' => 'Tags of the blog post',
1538
            'ger-DE' => 'Schlagworte des Blog-Eintrages',
1539
        ];
1540
        $fieldDefCreate->fieldGroup = 'blog-meta';
1541
        $fieldDefCreate->position = 1;
1542
        $fieldDefCreate->isTranslatable = true;
1543
        $fieldDefCreate->isRequired = true;
1544
        $fieldDefCreate->isInfoCollector = false;
1545
        $fieldDefCreate->validatorConfiguration = [
1546
            'StringLengthValidator' => [
1547
                'minStringLength' => 0,
1548
                'maxStringLength' => 0,
1549
            ],
1550
        ];
1551
        $fieldDefCreate->fieldSettings = [];
1552
        $fieldDefCreate->isSearchable = true;
1553
        $fieldDefCreate->defaultValue = 'default tags';
1554
1555
        $contentTypeService->addFieldDefinition($contentTypeDraft, $fieldDefCreate);
1556
        /* END: Use Case */
1557
1558
        $loadedType = $contentTypeService->loadContentTypeDraft($contentTypeDraft->id);
1559
1560
        $this->assertInstanceOf(
1561
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeDraft',
1562
            $loadedType
1563
        );
1564
1565
        return [
1566
            'loadedType' => $loadedType,
1567
            'fieldDefCreate' => $fieldDefCreate,
1568
        ];
1569
    }
1570
1571
    /**
1572
     * Test for the addFieldDefinition() method.
1573
     *
1574
     * @see \eZ\Publish\API\Repository\ContentTypeService::addFieldDefinition()
1575
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAddFieldDefinition
1576
     */
1577
    public function testAddFieldDefinitionStructValues(array $data)
1578
    {
1579
        $loadedType = $data['loadedType'];
1580
        $fieldDefCreate = $data['fieldDefCreate'];
1581
1582
        foreach ($loadedType->fieldDefinitions as $fieldDefinition) {
1583
            if ($fieldDefinition->identifier == $fieldDefCreate->identifier) {
1584
                $this->assertFieldDefinitionsEqual($fieldDefCreate, $fieldDefinition);
1585
1586
                return;
1587
            }
1588
        }
1589
1590
        $this->fail(
1591
            sprintf(
1592
                'Could not create Field definition with identifier "%s".',
1593
                $fieldDefCreate->identifier
1594
            )
1595
        );
1596
    }
1597
1598
    /**
1599
     * Test for the addFieldDefinition() method.
1600
     *
1601
     * @see \eZ\Publish\API\Repository\ContentTypeService::addFieldDefinition()
1602
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAddFieldDefinition
1603
     */
1604 View Code Duplication
    public function testAddFieldDefinitionThrowsInvalidArgumentExceptionDuplicateFieldIdentifier()
1605
    {
1606
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1607
1608
        $repository = $this->getRepository();
1609
        $contentTypeService = $repository->getContentTypeService();
1610
1611
        /* BEGIN: Use Case */
1612
        $contentTypeDraft = $this->createContentTypeDraft();
1613
1614
        $fieldDefCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
1615
1616
        // Throws an exception
1617
        $contentTypeService->addFieldDefinition($contentTypeDraft, $fieldDefCreate);
1618
        /* END: Use Case */
1619
    }
1620
1621
    /**
1622
     * Test for the addFieldDefinition() method.
1623
     *
1624
     * Testing that field definition of non-repeatable field type can not be added multiple
1625
     * times to the same ContentType.
1626
     *
1627
     * @see \eZ\Publish\API\Repository\ContentTypeService::addFieldDefinition()
1628
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAddFieldDefinition
1629
     */
1630
    public function testAddFieldDefinitionThrowsContentTypeFieldDefinitionValidationException()
1631
    {
1632
        $repository = $this->getRepository();
1633
        $contentTypeService = $repository->getContentTypeService();
1634
1635
        /* BEGIN: Use Case */
1636
        $userContentType = $contentTypeService->loadContentTypeByIdentifier('user');
1637
        $userContentTypeDraft = $contentTypeService->createContentTypeDraft($userContentType);
1638
1639
        $fieldDefCreate = $contentTypeService->newFieldDefinitionCreateStruct('temperature', 'ezinteger');
1640
        $fieldDefCreate->isSearchable = true;
1641
        $fieldDefCreate->validatorConfiguration = [
1642
            'IntegerValueValidator' => [
1643
                'minIntegerValue' => 42,
1644
                'maxIntegerValue' => 75.3,
1645
            ],
1646
        ];
1647
        $fieldDefCreate->fieldGroup = 'blog-meta';
1648
        $fieldDefCreate->position = 1;
1649
        $fieldDefCreate->isTranslatable = false;
1650
        $fieldDefCreate->isRequired = true;
1651
        $fieldDefCreate->isInfoCollector = false;
1652
        $fieldDefCreate->fieldSettings = [];
1653
1654
        try {
1655
            // Throws an exception because field's validator configuration is invalid
1656
            $contentTypeService->addFieldDefinition($userContentTypeDraft, $fieldDefCreate);
1657
        } catch (ContentTypeFieldDefinitionValidationException $e) {
1658
            $validationErrors = $e->getFieldErrors();
1659
        }
1660
        /* END: Use Case */
1661
1662
        /* @var $validationErrors */
1663
        $this->assertTrue(isset($validationErrors));
1664
        $this->assertIsArray($validationErrors);
0 ignored issues
show
Bug introduced by
The variable $validationErrors does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1665
        $this->assertCount(1, $validationErrors);
1666
        $this->assertArrayHasKey('temperature', $validationErrors);
1667
        $this->assertIsArray($validationErrors['temperature']);
1668
        $this->assertCount(1, $validationErrors['temperature']);
1669
        $this->assertInstanceOf('eZ\\Publish\\Core\\FieldType\\ValidationError', $validationErrors['temperature'][0]);
1670
1671
        $this->assertEquals(
1672
            new Message(
1673
                "Validator parameter '%parameter%' value must be of integer type",
1674
                ['%parameter%' => 'maxIntegerValue']
1675
            ),
1676
            $validationErrors['temperature'][0]->getTranslatableMessage()
1677
        );
1678
    }
1679
1680
    /**
1681
     * Test for the addFieldDefinition() method.
1682
     *
1683
     * Testing that field definition of non-repeatable field type can not be added multiple
1684
     * times to the same ContentType.
1685
     *
1686
     * @see \eZ\Publish\API\Repository\ContentTypeService::addFieldDefinition()
1687
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAddFieldDefinition
1688
     */
1689 View Code Duplication
    public function testAddFieldDefinitionThrowsBadStateExceptionNonRepeatableField()
1690
    {
1691
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
1692
        $this->expectExceptionMessage('The Content Type already contains a Field definition of the singular Field Type \'ezuser\'');
1693
1694
        $repository = $this->getRepository();
1695
        $contentTypeService = $repository->getContentTypeService();
1696
1697
        /* BEGIN: Use Case */
1698
        $userContentType = $contentTypeService->loadContentTypeByIdentifier('user');
1699
        $userContentTypeDraft = $contentTypeService->createContentTypeDraft($userContentType);
1700
1701
        $fieldDefCreate = $contentTypeService->newFieldDefinitionCreateStruct('second_user_account', 'ezuser');
1702
        $fieldDefCreate->names = [
1703
            'eng-GB' => 'Second user account',
1704
        ];
1705
        $fieldDefCreate->descriptions = [
1706
            'eng-GB' => 'Second user account for the ContentType',
1707
        ];
1708
        $fieldDefCreate->fieldGroup = 'users';
1709
        $fieldDefCreate->position = 1;
1710
        $fieldDefCreate->isTranslatable = false;
1711
        $fieldDefCreate->isRequired = true;
1712
        $fieldDefCreate->isInfoCollector = false;
1713
        $fieldDefCreate->validatorConfiguration = [];
1714
        $fieldDefCreate->fieldSettings = [];
1715
        $fieldDefCreate->isSearchable = false;
1716
1717
        // Throws an exception because $userContentTypeDraft already contains non-repeatable field type definition 'ezuser'
1718
        $contentTypeService->addFieldDefinition($userContentTypeDraft, $fieldDefCreate);
1719
        /* END: Use Case */
1720
    }
1721
1722
    /**
1723
     * Test for the ContentTypeService::createContentType() method.
1724
     *
1725
     * Testing that field definition of non-repeatable field type can not be added multiple
1726
     * times to the same ContentTypeCreateStruct.
1727
     *
1728
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentType()
1729
     */
1730
    public function testCreateContentThrowsContentTypeValidationException()
1731
    {
1732
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\ContentTypeValidationException::class);
1733
        $this->expectExceptionMessage('Field Type \'ezuser\' is singular and cannot be used more than once in a Content Type');
1734
1735
        $repository = $this->getRepository();
1736
1737
        /* BEGIN: Use Case */
1738
        $contentTypeService = $repository->getContentTypeService();
1739
        $contentTypeCreateStruct = $contentTypeService->newContentTypeCreateStruct('this_is_new');
1740
        $contentTypeCreateStruct->names = ['eng-GB' => 'This is new'];
1741
        $contentTypeCreateStruct->mainLanguageCode = 'eng-GB';
1742
1743
        // create first field definition
1744
        $firstFieldDefinition = $contentTypeService->newFieldDefinitionCreateStruct(
1745
            'first_user',
1746
            'ezuser'
1747
        );
1748
        $firstFieldDefinition->names = [
1749
            'eng-GB' => 'First user account',
1750
        ];
1751
        $firstFieldDefinition->position = 1;
1752
1753
        $contentTypeCreateStruct->addFieldDefinition($firstFieldDefinition);
1754
1755
        // create second field definition
1756
        $secondFieldDefinition = $contentTypeService->newFieldDefinitionCreateStruct(
1757
            'second_user',
1758
            'ezuser'
1759
        );
1760
        $secondFieldDefinition->names = [
1761
            'eng-GB' => 'Second user account',
1762
        ];
1763
        $secondFieldDefinition->position = 2;
1764
1765
        $contentTypeCreateStruct->addFieldDefinition($secondFieldDefinition);
1766
1767
        // Throws an exception because the ContentTypeCreateStruct has a singular field repeated
1768
        $contentTypeService->createContentType(
1769
            $contentTypeCreateStruct,
1770
            [$contentTypeService->loadContentTypeGroupByIdentifier('Content')]
1771
        );
1772
        /* END: Use Case */
1773
    }
1774
1775
    /**
1776
     * Test for the addFieldDefinition() method.
1777
     *
1778
     * Testing adding field definition of the field type that can not be added to the ContentType that
1779
     * already has Content instances.
1780
     *
1781
     * @see \eZ\Publish\API\Repository\ContentTypeService::addFieldDefinition()
1782
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAddFieldDefinition
1783
     */
1784 View Code Duplication
    public function testAddFieldDefinitionThrowsBadStateExceptionContentInstances()
1785
    {
1786
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
1787
        $this->expectExceptionMessage('A Field definition of the \'ezuser\' Field Type cannot be added because the Content Type already has Content items');
1788
1789
        $repository = $this->getRepository();
1790
        $contentTypeService = $repository->getContentTypeService();
1791
1792
        /* BEGIN: Use Case */
1793
        $folderContentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1794
        $folderContentTypeDraft = $contentTypeService->createContentTypeDraft($folderContentType);
1795
1796
        $fieldDefCreate = $contentTypeService->newFieldDefinitionCreateStruct('user_account', 'ezuser');
1797
        $fieldDefCreate->names = [
1798
            'eng-GB' => 'User account',
1799
        ];
1800
        $fieldDefCreate->descriptions = [
1801
            'eng-GB' => 'User account field definition for ContentType that has Content instances',
1802
        ];
1803
        $fieldDefCreate->fieldGroup = 'users';
1804
        $fieldDefCreate->position = 1;
1805
        $fieldDefCreate->isTranslatable = false;
1806
        $fieldDefCreate->isRequired = true;
1807
        $fieldDefCreate->isInfoCollector = false;
1808
        $fieldDefCreate->validatorConfiguration = [];
1809
        $fieldDefCreate->fieldSettings = [];
1810
        $fieldDefCreate->isSearchable = false;
1811
1812
        // Throws an exception because 'ezuser' type field definition can't be added to ContentType that already has Content instances
1813
        $contentTypeService->addFieldDefinition($folderContentTypeDraft, $fieldDefCreate);
1814
        /* END: Use Case */
1815
    }
1816
1817
    /**
1818
     * Test for the removeFieldDefinition() method.
1819
     *
1820
     * @return array
1821
     *
1822
     * @see \eZ\Publish\API\Repository\ContentTypeService::removeFieldDefinition()
1823
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
1824
     */
1825
    public function testRemoveFieldDefinition()
1826
    {
1827
        $repository = $this->getRepository();
1828
        $contentTypeService = $repository->getContentTypeService();
1829
1830
        /* BEGIN: Use Case */
1831
        $contentTypeDraft = $this->createContentTypeDraft();
1832
1833
        $bodyField = $contentTypeDraft->getFieldDefinition('body');
1834
1835
        $contentTypeService->removeFieldDefinition($contentTypeDraft, $bodyField);
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 1833 can be null; however, eZ\Publish\API\Repositor...removeFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1836
        /* END: Use Case */
1837
1838
        $loadedType = $contentTypeService->loadContentTypeDraft($contentTypeDraft->id);
1839
1840
        $this->assertInstanceOf(
1841
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeDraft',
1842
            $loadedType
1843
        );
1844
1845
        return [
1846
            'removedFieldDefinition' => $bodyField,
1847
            'loadedType' => $loadedType,
1848
        ];
1849
    }
1850
1851
    /**
1852
     * Test for the removeFieldDefinition() method.
1853
     *
1854
     * @param array $data
1855
     *
1856
     * @see \eZ\Publish\API\Repository\ContentTypeService::removeFieldDefinition()
1857
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testRemoveFieldDefinition
1858
     */
1859
    public function testRemoveFieldDefinitionRemoved(array $data)
1860
    {
1861
        $removedFieldDefinition = $data['removedFieldDefinition'];
1862
        $loadedType = $data['loadedType'];
1863
1864
        foreach ($loadedType->fieldDefinitions as $fieldDefinition) {
1865
            if ($fieldDefinition->identifier == $removedFieldDefinition->identifier) {
1866
                $this->fail(
1867
                    sprintf(
1868
                        'Field definition with identifier "%s" not removed.',
1869
                        $removedFieldDefinition->identifier
1870
                    )
1871
                );
1872
            }
1873
        }
1874
    }
1875
1876
    /**
1877
     * Test for the removeFieldDefinition() method.
1878
     *
1879
     * @see \eZ\Publish\API\Repository\ContentTypeService::removeFieldDefinition()
1880
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testRemoveFieldDefinition
1881
     */
1882
    public function testRemoveFieldDefinitionThrowsInvalidArgumentException()
1883
    {
1884
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1885
1886
        $repository = $this->getRepository();
1887
        $contentTypeService = $repository->getContentTypeService();
1888
1889
        /* BEGIN: Use Case */
1890
        $contentTypeDraft = $this->createContentTypeDraft();
1891
1892
        $bodyField = $contentTypeDraft->getFieldDefinition('body');
1893
        $contentTypeService->removeFieldDefinition($contentTypeDraft, $bodyField);
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 1892 can be null; however, eZ\Publish\API\Repositor...removeFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1894
1895
        $loadedDraft = $contentTypeService->loadContentTypeDraft($contentTypeDraft->id);
1896
1897
        // Throws exception, sine "body" has already been removed
1898
        $contentTypeService->removeFieldDefinition($loadedDraft, $bodyField);
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 1892 can be null; however, eZ\Publish\API\Repositor...removeFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1899
        /* END: Use Case */
1900
    }
1901
1902
    /**
1903
     * Test removeFieldDefinition() method for field in a different draft throws an exception.
1904
     *
1905
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testRemoveFieldDefinition
1906
     * @covers \eZ\Publish\Core\Repository\ContentTypeService::removeFieldDefinition
1907
     */
1908 View Code Duplication
    public function testRemoveFieldDefinitionThrowsInvalidArgumentExceptionOnWrongDraft()
1909
    {
1910
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1911
1912
        $repository = $this->getRepository();
1913
        $contentTypeService = $repository->getContentTypeService();
1914
1915
        $contentTypeDraft01 = $this->createContentTypeDraft();
1916
        $contentTypeDraft02 = $this->createContentTypeDraft();
1917
1918
        $bodyField = $contentTypeDraft02->getFieldDefinition('body');
1919
1920
        // Throws an exception because $bodyField field belongs to another draft
1921
        $contentTypeService->removeFieldDefinition($contentTypeDraft01, $bodyField);
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft02->getFieldDefinition('body') on line 1918 can be null; however, eZ\Publish\API\Repositor...removeFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1922
    }
1923
1924
    /**
1925
     * Test for the removeFieldDefinition() method.
1926
     *
1927
     * @see \eZ\Publish\API\Repository\ContentTypeService::removeFieldDefinition()
1928
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testRemoveFieldDefinition
1929
     */
1930
    public function testRemoveFieldDefinitionRemovesFieldFromContent()
1931
    {
1932
        $repository = $this->getRepository();
1933
1934
        $contentTypeService = $repository->getContentTypeService();
1935
        $contentService = $repository->getContentService();
1936
1937
        // Create ContentType
1938
        $contentTypeDraft = $this->createContentTypeDraft();
1939
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1940
        $publishedType = $contentTypeService->loadContentType($contentTypeDraft->id);
1941
1942
        // Create multi-language Content in all 3 possible versions
1943
        $contentDraft = $this->createContentDraft();
1944
        $archivedContent = $contentService->publishVersion($contentDraft->versionInfo);
1945
        $contentDraft = $contentService->createContentDraft($archivedContent->contentInfo);
1946
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
1947
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
1948
1949
        // Remove field definition from ContentType
1950
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($publishedType);
1951
        $bodyField = $contentTypeDraft->getFieldDefinition('body');
1952
        $contentTypeService->removeFieldDefinition($contentTypeDraft, $bodyField);
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 1951 can be null; however, eZ\Publish\API\Repositor...removeFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1953
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1954
1955
        // Reload all versions
1956
        $contentVersion1Archived = $contentService->loadContent(
1957
            $archivedContent->contentInfo->id,
1958
            null,
1959
            $archivedContent->versionInfo->versionNo
1960
        );
1961
        $contentVersion2Published = $contentService->loadContent(
1962
            $publishedContent->contentInfo->id,
1963
            null,
1964
            $publishedContent->versionInfo->versionNo
1965
        );
1966
        $contentVersion3Draft = $contentService->loadContent(
1967
            $draftContent->contentInfo->id,
1968
            null,
1969
            $draftContent->versionInfo->versionNo
1970
        );
1971
1972
        $this->assertInstanceOf(
1973
            'eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1974
            $contentVersion1Archived
1975
        );
1976
        $this->assertInstanceOf(
1977
            'eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1978
            $contentVersion2Published
1979
        );
1980
        $this->assertInstanceOf(
1981
            'eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1982
            $contentVersion3Draft
1983
        );
1984
1985
        return [
1986
            $contentVersion1Archived,
1987
            $contentVersion2Published,
1988
            $contentVersion3Draft,
1989
        ];
1990
    }
1991
1992
    /**
1993
     * Test for the removeFieldDefinition() method.
1994
     *
1995
     * @param \eZ\Publish\API\Repository\Values\Content\Content[] $data
1996
     *
1997
     * @see \eZ\Publish\API\Repository\ContentTypeService::removeFieldDefinition()
1998
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testRemoveFieldDefinitionRemovesFieldFromContent
1999
     */
2000
    public function testRemoveFieldDefinitionRemovesFieldFromContentRemoved($data)
2001
    {
2002
        list(
2003
            $contentVersion1Archived,
2004
            $contentVersion1Published,
2005
            $contentVersion2Draft
2006
        ) = $data;
2007
2008
        $this->assertFalse(
2009
            isset($contentVersion1Archived->fields['body']),
2010
            'The field was not removed from archived version.'
2011
        );
2012
        $this->assertFalse(
2013
            isset($contentVersion1Published->fields['body']),
2014
            'The field was not removed from published version.'
2015
        );
2016
        $this->assertFalse(
2017
            isset($contentVersion2Draft->fields['body']),
2018
            'The field was not removed from draft version.'
2019
        );
2020
    }
2021
2022
    /**
2023
     * Test for the addFieldDefinition() method.
2024
     *
2025
     * @see \eZ\Publish\API\Repository\ContentTypeService::addFieldDefinition()
2026
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAddFieldDefinition
2027
     */
2028
    public function testAddFieldDefinitionAddsFieldToContent()
2029
    {
2030
        $repository = $this->getRepository();
2031
2032
        $contentTypeService = $repository->getContentTypeService();
2033
        $contentService = $repository->getContentService();
2034
2035
        // Create ContentType
2036
        $contentTypeDraft = $this->createContentTypeDraft();
2037
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
2038
        $publishedType = $contentTypeService->loadContentType($contentTypeDraft->id);
2039
2040
        // Create multi-language Content in all 3 possible versions
2041
        $contentDraft = $this->createContentDraft();
2042
        $archivedContent = $contentService->publishVersion($contentDraft->versionInfo);
2043
        $contentDraft = $contentService->createContentDraft($archivedContent->contentInfo);
2044
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
2045
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
2046
2047
        // Add field definition to ContentType
2048
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($publishedType);
2049
2050
        $fieldDefinitionCreateStruct = $contentTypeService->newFieldDefinitionCreateStruct('byline', 'ezstring');
2051
        $fieldDefinitionCreateStruct->names = [
2052
            'eng-US' => 'Byline',
2053
        ];
2054
        $fieldDefinitionCreateStruct->descriptions = [
2055
            'eng-US' => 'Byline of the blog post',
2056
        ];
2057
        $fieldDefinitionCreateStruct->fieldGroup = 'blog-meta';
2058
        $fieldDefinitionCreateStruct->position = 1;
2059
        $fieldDefinitionCreateStruct->isTranslatable = true;
2060
        $fieldDefinitionCreateStruct->isRequired = true;
2061
        $fieldDefinitionCreateStruct->isInfoCollector = false;
2062
        $fieldDefinitionCreateStruct->validatorConfiguration = [
2063
            'StringLengthValidator' => [
2064
                'minStringLength' => 0,
2065
                'maxStringLength' => 0,
2066
            ],
2067
        ];
2068
        $fieldDefinitionCreateStruct->fieldSettings = [];
2069
        $fieldDefinitionCreateStruct->isSearchable = true;
2070
2071
        $contentTypeService->addFieldDefinition($contentTypeDraft, $fieldDefinitionCreateStruct);
2072
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
2073
2074
        // Reload all versions
2075
        $contentVersion1Archived = $contentService->loadContent(
2076
            $archivedContent->contentInfo->id,
2077
            null,
2078
            $archivedContent->versionInfo->versionNo
2079
        );
2080
        $contentVersion2Published = $contentService->loadContent(
2081
            $publishedContent->contentInfo->id,
2082
            null,
2083
            $publishedContent->versionInfo->versionNo
2084
        );
2085
        $contentVersion3Draft = $contentService->loadContent(
2086
            $draftContent->contentInfo->id,
2087
            null,
2088
            $draftContent->versionInfo->versionNo
2089
        );
2090
2091
        $this->assertInstanceOf(
2092
            'eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
2093
            $contentVersion1Archived
2094
        );
2095
        $this->assertInstanceOf(
2096
            'eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
2097
            $contentVersion2Published
2098
        );
2099
        $this->assertInstanceOf(
2100
            'eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
2101
            $contentVersion3Draft
2102
        );
2103
2104
        return [
2105
            $contentVersion1Archived,
2106
            $contentVersion2Published,
2107
            $contentVersion3Draft,
2108
        ];
2109
    }
2110
2111
    /**
2112
     * Test for the addFieldDefinition() method.
2113
     *
2114
     * @param \eZ\Publish\API\Repository\Values\Content\Content[] $data
2115
     *
2116
     * @see \eZ\Publish\API\Repository\ContentTypeService::addFieldDefinition()
2117
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAddFieldDefinitionAddsFieldToContent
2118
     */
2119
    public function testAddFieldDefinitionAddsFieldToContentAdded(array $data)
2120
    {
2121
        list(
2122
            $contentVersion1Archived,
2123
            $contentVersion1Published,
2124
            $contentVersion2Draft
2125
            ) = $data;
2126
2127
        $this->assertTrue(
2128
            isset($contentVersion1Archived->fields['byline']),
2129
            'New field was not added to archived version.'
2130
        );
2131
        $this->assertTrue(
2132
            isset($contentVersion1Published->fields['byline']),
2133
            'New field was not added to published version.'
2134
        );
2135
        $this->assertTrue(
2136
            isset($contentVersion2Draft->fields['byline']),
2137
            'New field was not added to draft version.'
2138
        );
2139
2140
        $this->assertEquals(
2141
            $contentVersion1Archived->getField('byline')->id,
2142
            $contentVersion1Published->getField('byline')->id
2143
        );
2144
        $this->assertEquals(
2145
            $contentVersion1Published->getField('byline')->id,
2146
            $contentVersion2Draft->getField('byline')->id
2147
        );
2148
    }
2149
2150
    /**
2151
     * Test for the newFieldDefinitionUpdateStruct() method.
2152
     *
2153
     * @see \eZ\Publish\API\Repository\ContentTypeService::newFieldDefinitionUpdateStruct()
2154
     */
2155
    public function testNewFieldDefinitionUpdateStruct()
2156
    {
2157
        $repository = $this->getRepository();
2158
        /* BEGIN: Use Case */
2159
        // $draftId contains the ID of a content type draft
2160
        $contentTypeService = $repository->getContentTypeService();
2161
2162
        $updateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
2163
        /* END: Use Case */
2164
2165
        $this->assertInstanceOf(
2166
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\FieldDefinitionUpdateStruct',
2167
            $updateStruct
2168
        );
2169
2170
        return $updateStruct;
2171
    }
2172
2173
    /**
2174
     * Test for the newFieldDefinitionUpdateStruct() method.
2175
     *
2176
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testNewFieldDefinitionUpdateStruct
2177
     * @covers \eZ\Publish\Core\Repository\ContentTypeService::newContentTypeUpdateStruct
2178
     *
2179
     * @param \eZ\Publish\API\Repository\Values\ContentType\FieldDefinitionUpdateStruct $fieldDefinitionUpdateStruct
2180
     */
2181
    public function testNewFieldDefinitionUpdateStructValues($fieldDefinitionUpdateStruct)
2182
    {
2183
        foreach ($fieldDefinitionUpdateStruct as $propertyName => $propertyValue) {
0 ignored issues
show
Bug introduced by
The expression $fieldDefinitionUpdateStruct of type object<eZ\Publish\API\Re...DefinitionUpdateStruct> is not traversable.
Loading history...
2184
            $this->assertNull(
2185
                $propertyValue,
2186
                "Property '$propertyName' is not null."
2187
            );
2188
        }
2189
    }
2190
2191
    /**
2192
     * Test for the updateFieldDefinition() method.
2193
     *
2194
     * @return array
2195
     *
2196
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateFieldDefinition()
2197
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeDraft
2198
     */
2199
    public function testUpdateFieldDefinition()
2200
    {
2201
        $repository = $this->getRepository();
2202
        $contentTypeService = $repository->getContentTypeService();
2203
2204
        /* BEGIN: Use Case */
2205
        $contentTypeDraft = $this->createContentTypeDraft();
2206
2207
        $bodyField = $contentTypeDraft->getFieldDefinition('body');
2208
2209
        $bodyUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
2210
        $bodyUpdateStruct->identifier = 'blog-body';
2211
        $bodyUpdateStruct->names = [
2212
            'eng-GB' => 'Blog post body',
2213
            'ger-DE' => 'Blog-Eintrags-Textkörper',
2214
        ];
2215
        $bodyUpdateStruct->descriptions = [
2216
            'eng-GB' => 'Blog post body of the blog post',
2217
            'ger-DE' => 'Blog-Eintrags-Textkörper des Blog-Eintrages',
2218
        ];
2219
        $bodyUpdateStruct->fieldGroup = 'updated-blog-content';
2220
        $bodyUpdateStruct->position = 3;
2221
        $bodyUpdateStruct->isTranslatable = false;
2222
        $bodyUpdateStruct->isRequired = false;
2223
        $bodyUpdateStruct->isInfoCollector = true;
2224
        $bodyUpdateStruct->validatorConfiguration = [];
2225
        $bodyUpdateStruct->fieldSettings = [
2226
            'textRows' => 60,
2227
        ];
2228
        $bodyUpdateStruct->isSearchable = false;
2229
2230
        $contentTypeService->updateFieldDefinition(
2231
            $contentTypeDraft,
2232
            $bodyField,
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 2207 can be null; however, eZ\Publish\API\Repositor...updateFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2233
            $bodyUpdateStruct
2234
        );
2235
        /* END: Use Case */
2236
2237
        $loadedDraft = $contentTypeService->loadContentTypeDraft($contentTypeDraft->id);
2238
        $this->assertInstanceOf(
2239
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\FieldDefinition',
2240
            ($loadedField = $loadedDraft->getFieldDefinition('blog-body'))
2241
        );
2242
2243
        return [
2244
            'originalField' => $bodyField,
2245
            'updatedField' => $loadedField,
2246
            'updateStruct' => $bodyUpdateStruct,
2247
        ];
2248
    }
2249
2250
    /**
2251
     * @covers \eZ\Publish\API\Repository\ContentTypeService::updateFieldDefinition
2252
     */
2253
    public function testUpdateFieldDefinitionWithNewTranslation()
2254
    {
2255
        $repository = $this->getRepository();
2256
        $contentTypeService = $repository->getContentTypeService();
2257
2258
        /* BEGIN: Use Case */
2259
        $contentTypeDraft = $this->createContentTypeDraft();
2260
2261
        $bodyField = $contentTypeDraft->getFieldDefinition('body');
2262
2263
        self::assertEquals(
2264
            ['eng-US', 'ger-DE'],
2265
            array_keys($bodyField->getNames())
2266
        );
2267
2268
        $bodyUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
2269
        $bodyUpdateStruct->identifier = 'blog-body';
2270
        $bodyUpdateStruct->names = [
2271
            'eng-GB' => 'New blog post body',
2272
        ];
2273
        $bodyUpdateStruct->descriptions = [
2274
            'eng-GB' => null,
2275
        ];
2276
        $bodyUpdateStruct->fieldGroup = 'updated-blog-content';
2277
        $bodyUpdateStruct->position = 3;
2278
        $bodyUpdateStruct->isTranslatable = false;
2279
        $bodyUpdateStruct->isRequired = false;
2280
        $bodyUpdateStruct->isInfoCollector = true;
2281
        $bodyUpdateStruct->validatorConfiguration = [];
2282
        $bodyUpdateStruct->fieldSettings = [
2283
            'textRows' => 60,
2284
        ];
2285
        $bodyUpdateStruct->isSearchable = false;
2286
2287
        $contentTypeService->updateFieldDefinition(
2288
            $contentTypeDraft,
2289
            $bodyField,
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 2261 can be null; however, eZ\Publish\API\Repositor...updateFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2290
            $bodyUpdateStruct
2291
        );
2292
        /* END: Use Case */
2293
2294
        $contentType = $contentTypeService->loadContentTypeDraft($contentTypeDraft->id);
2295
2296
        self::assertEquals(
2297
            [
2298
                'eng-GB' => 'New blog post body',
2299
                'eng-US' => 'Body',
2300
                'ger-DE' => 'Textkörper',
2301
            ],
2302
            $contentType->getFieldDefinition('blog-body')->getNames()
2303
        );
2304
        self::assertEquals(
2305
            [
2306
                'eng-GB' => null,
2307
                'eng-US' => 'Body of the blog post',
2308
                'ger-DE' => 'Textkörper des Blog-Eintrages',
2309
            ],
2310
            $contentType->getFieldDefinition('blog-body')->getDescriptions()
2311
        );
2312
    }
2313
2314
    /**
2315
     * Test for the updateFieldDefinition() method.
2316
     *
2317
     * @param array $data
2318
     *
2319
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateFieldDefinition()
2320
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateFieldDefinition
2321
     */
2322
    public function testUpdateFieldDefinitionStructValues(array $data)
2323
    {
2324
        $originalField = $data['originalField'];
2325
        $updatedField = $data['updatedField'];
2326
        $updateStruct = $data['updateStruct'];
2327
2328
        $this->assertPropertiesCorrect(
2329
            [
2330
                'id' => $originalField->id,
2331
                'identifier' => $updateStruct->identifier,
2332
                'names' => $updateStruct->names,
2333
                'descriptions' => $updateStruct->descriptions,
2334
                'fieldGroup' => $updateStruct->fieldGroup,
2335
                'position' => $updateStruct->position,
2336
                'fieldTypeIdentifier' => $originalField->fieldTypeIdentifier,
2337
                'isTranslatable' => $updateStruct->isTranslatable,
2338
                'isRequired' => $updateStruct->isRequired,
2339
                'isInfoCollector' => $updateStruct->isInfoCollector,
2340
                'validatorConfiguration' => $updateStruct->validatorConfiguration,
2341
                'defaultValue' => $originalField->defaultValue,
2342
                'isSearchable' => $updateStruct->isSearchable,
2343
            ],
2344
            $updatedField
2345
        );
2346
    }
2347
2348
    /**
2349
     * Test for the updateFieldDefinition() method using an empty FieldDefinitionUpdateStruct.
2350
     *
2351
     * @see \eZ\Publish\API\Repository\Values\ContentType\FieldDefinitionUpdateStruct
2352
     *
2353
     * @covers \eZ\Publish\Core\Repository\ContentTypeService::updateFieldDefinition
2354
     */
2355
    public function testUpdateFieldDefinitionWithEmptyStruct()
2356
    {
2357
        $repository = $this->getRepository();
2358
        $contentTypeService = $repository->getContentTypeService();
2359
2360
        $contentTypeDraft = $this->createContentTypeDraft();
2361
        $fieldDefinition = $contentTypeDraft->getFieldDefinition('body');
2362
        $fieldDefinitionUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
2363
2364
        $contentTypeService->updateFieldDefinition(
2365
            $contentTypeDraft,
2366
            $fieldDefinition,
0 ignored issues
show
Bug introduced by
It seems like $fieldDefinition defined by $contentTypeDraft->getFieldDefinition('body') on line 2361 can be null; however, eZ\Publish\API\Repositor...updateFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2367
            $fieldDefinitionUpdateStruct
2368
        );
2369
        $contentTypeDraft = $contentTypeService->loadContentTypeDraft($contentTypeDraft->id);
2370
        $updatedFieldDefinition = $contentTypeDraft->getFieldDefinition('body');
2371
2372
        self::assertEquals(
2373
            $fieldDefinition,
2374
            $updatedFieldDefinition
2375
        );
2376
    }
2377
2378
    /**
2379
     * Test for the updateFieldDefinition() method with already defined field identifier.
2380
     *
2381
     * @covers \eZ\Publish\API\Repository\ContentTypeService::updateFieldDefinition
2382
     * depends \eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeDraft
2383
     */
2384
    public function testUpdateFieldDefinitionThrowsInvalidArgumentExceptionFieldIdentifierExists()
2385
    {
2386
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
2387
        $this->expectExceptionMessage('Argument \'$fieldDefinitionUpdateStruct\' is invalid: Another Field definition with identifier \'title\' exists in the Content Type');
2388
2389
        $repository = $this->getRepository();
2390
        $contentTypeService = $repository->getContentTypeService();
2391
2392
        /* BEGIN: Use Case */
2393
        $contentTypeDraft = $this->createContentTypeDraft();
2394
2395
        $bodyField = $contentTypeDraft->getFieldDefinition('body');
2396
        $titleField = $contentTypeDraft->getFieldDefinition('title');
0 ignored issues
show
Unused Code introduced by
$titleField 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...
2397
2398
        $bodyUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
2399
        $bodyUpdateStruct->identifier = 'title';
2400
2401
        // Throws exception, since "title" field already exists
2402
        $contentTypeService->updateFieldDefinition(
2403
            $contentTypeDraft,
2404
            $bodyField,
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 2395 can be null; however, eZ\Publish\API\Repositor...updateFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2405
            $bodyUpdateStruct
2406
        );
2407
        /* END: Use Case */
2408
    }
2409
2410
    /**
2411
     * Test for the updateFieldDefinition() method trying to update non-existent field.
2412
     *
2413
     * @covers \eZ\Publish\API\Repository\ContentTypeService::updateFieldDefinition()
2414
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeDraft
2415
     */
2416
    public function testUpdateFieldDefinitionThrowsInvalidArgumentExceptionForUndefinedField()
2417
    {
2418
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
2419
        $this->expectExceptionMessage('Argument \'$fieldDefinition\' is invalid: The given Field definition does not belong to the Content Type');
2420
2421
        $repository = $this->getRepository();
2422
        $contentTypeService = $repository->getContentTypeService();
2423
2424
        /* BEGIN: Use Case */
2425
        $contentTypeDraft = $this->createContentTypeDraft();
2426
2427
        $bodyField = $contentTypeDraft->getFieldDefinition('body');
2428
        $contentTypeService->removeFieldDefinition($contentTypeDraft, $bodyField);
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 2427 can be null; however, eZ\Publish\API\Repositor...removeFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2429
2430
        $loadedDraft = $contentTypeService->loadContentTypeDraft($contentTypeDraft->id);
2431
2432
        $bodyUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
2433
2434
        // Throws exception, since field "body" is already deleted
2435
        $contentTypeService->updateFieldDefinition(
2436
            $loadedDraft,
2437
            $bodyField,
0 ignored issues
show
Bug introduced by
It seems like $bodyField defined by $contentTypeDraft->getFieldDefinition('body') on line 2427 can be null; however, eZ\Publish\API\Repositor...updateFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2438
            $bodyUpdateStruct
2439
        );
2440
        /* END: Use Case */
2441
    }
2442
2443
    /**
2444
     * Test for the publishContentTypeDraft() method.
2445
     *
2446
     * @see \eZ\Publish\API\Repository\ContentTypeService::publishContentTypeDraft()
2447
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeDraft
2448
     */
2449
    public function testPublishContentTypeDraft()
2450
    {
2451
        $repository = $this->getRepository();
2452
        $contentTypeService = $repository->getContentTypeService();
2453
2454
        /* BEGIN: Use Case */
2455
        $contentTypeDraft = $this->createContentTypeDraft();
2456
2457
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
2458
        /* END: Use Case */
2459
2460
        $publishedType = $contentTypeService->loadContentType($contentTypeDraft->id);
2461
2462
        $this->assertInstanceOf(
2463
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType',
2464
            $publishedType
2465
        );
2466
        $this->assertNotInstanceOf(
2467
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeDraft',
2468
            $publishedType
2469
        );
2470
    }
2471
2472
    /**
2473
     * Test for the publishContentTypeDraft() method setting proper ContentType nameSchema.
2474
     *
2475
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testPublishContentTypeDraft
2476
     * @covers \eZ\Publish\Core\Repository\ContentTypeService::publishContentTypeDraft
2477
     */
2478
    public function testPublishContentTypeDraftSetsNameSchema()
2479
    {
2480
        $repository = $this->getRepository();
2481
        $contentTypeService = $repository->getContentTypeService();
2482
2483
        $typeCreateStruct = $contentTypeService->newContentTypeCreateStruct(
2484
            'new-type'
2485
        );
2486
        $typeCreateStruct->names = [
2487
            'eng-GB' => 'Type title',
2488
        ];
2489
        $typeCreateStruct->mainLanguageCode = 'eng-GB';
2490
2491
        $titleFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
2492
        $titleFieldCreate->position = 1;
2493
        $typeCreateStruct->addFieldDefinition($titleFieldCreate);
2494
2495
        $type = $contentTypeService->createContentType(
2496
            $typeCreateStruct,
2497
            [
2498
                $contentTypeService->loadContentTypeGroupByIdentifier('Content'),
2499
            ]
2500
        );
2501
2502
        $contentTypeService->publishContentTypeDraft($type);
2503
2504
        $loadedContentType = $contentTypeService->loadContentType($type->id);
2505
2506
        $this->assertEquals('<title>', $loadedContentType->nameSchema);
2507
    }
2508
2509
    /**
2510
     * Test that publishing Content Type Draft refreshes list of Content Types in Content Type Groups.
2511
     *
2512
     * @covers \eZ\Publish\API\Repository\ContentTypeService::publishContentTypeDraft
2513
     */
2514
    public function testPublishContentTypeDraftRefreshesContentTypesList()
2515
    {
2516
        $repository = $this->getRepository();
2517
        $contentTypeService = $repository->getContentTypeService();
2518
2519
        $contentTypeDraft = $this->createContentTypeDraft();
2520
2521
        // Make sure to 1. check draft is not part of lists, and 2. warm cache to make sure it invalidates
2522
        $contentTypes = $contentTypeService->loadContentTypeList([1, $contentTypeDraft->id]);
2523
        self::assertArrayNotHasKey($contentTypeDraft->id, $contentTypes);
2524
        self::assertCount(1, $contentTypes);
0 ignored issues
show
Bug introduced by
It seems like $contentTypes defined by $contentTypeService->loa...$contentTypeDraft->id)) on line 2522 can also be of type array<integer,object<eZ\...ntentType\ContentType>>; however, PHPUnit\Framework\Assert::assertCount() does only seem to accept object<Countable>|object...nit\Framework\iterable>, 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...
2525
2526
        $contentTypeGroups = $contentTypeDraft->getContentTypeGroups();
2527 View Code Duplication
        foreach ($contentTypeGroups as $contentTypeGroup) {
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...
2528
            $contentTypes = $contentTypeService->loadContentTypes($contentTypeGroup);
2529
            // check if not published Content Type does not exist on published Content Types list
2530
            self::assertNotContains(
2531
                $contentTypeDraft->id,
2532
                array_map(
2533
                    function (ContentType $contentType) {
2534
                        return $contentType->id;
2535
                    },
2536
                    $contentTypes
2537
                )
2538
            );
2539
        }
2540
2541
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
2542
2543
        // After publishing it should be part of lists
2544
        $contentTypes = $contentTypeService->loadContentTypeList([1, $contentTypeDraft->id]);
2545
        self::assertArrayHasKey($contentTypeDraft->id, $contentTypes);
2546
        self::assertCount(2, $contentTypes);
0 ignored issues
show
Bug introduced by
It seems like $contentTypes defined by $contentTypeService->loa...$contentTypeDraft->id)) on line 2544 can also be of type array<integer,object<eZ\...ntentType\ContentType>>; however, PHPUnit\Framework\Assert::assertCount() does only seem to accept object<Countable>|object...nit\Framework\iterable>, 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...
2547
2548 View Code Duplication
        foreach ($contentTypeGroups as $contentTypeGroup) {
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...
2549
            $contentTypes = $contentTypeService->loadContentTypes($contentTypeGroup);
2550
            // check if published Content is available in published Content Types list
2551
            self::assertContains(
2552
                $contentTypeDraft->id,
2553
                array_map(
2554
                    function (ContentType $contentType) {
2555
                        return $contentType->id;
2556
                    },
2557
                    $contentTypes
2558
                )
2559
            );
2560
        }
2561
    }
2562
2563
    /**
2564
     * Test for the publishContentTypeDraft() method.
2565
     *
2566
     * @see \eZ\Publish\API\Repository\ContentTypeService::publishContentTypeDraft()
2567
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testPublishContentTypeDraft
2568
     */
2569
    public function testPublishContentTypeDraftThrowsBadStateException()
2570
    {
2571
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
2572
2573
        $repository = $this->getRepository();
2574
        $contentTypeService = $repository->getContentTypeService();
2575
2576
        /* BEGIN: Use Case */
2577
        $contentTypeDraft = $this->createContentTypeDraft();
2578
2579
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
2580
2581
        // Throws exception, since no draft exists anymore
2582
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
2583
        /* END: Use Case */
2584
    }
2585
2586
    /**
2587
     * Test for the createContentTypeGroup() method trying to create Content Type without any fields.
2588
     *
2589
     * @covers \eZ\Publish\API\Repository\ContentTypeService::publishContentTypeDraft()
2590
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testPublishContentTypeDraft
2591
     */
2592
    public function testPublishContentTypeDraftThrowsInvalidArgumentExceptionWithoutFields()
2593
    {
2594
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\InvalidArgumentException::class);
2595
        $this->expectExceptionMessage('Argument \'$contentTypeDraft\' is invalid: The Content Type draft should have at least one Field definition');
2596
2597
        $repository = $this->getRepository();
2598
        $contentTypeService = $repository->getContentTypeService();
2599
2600
        $typeCreateStruct = $contentTypeService->newContentTypeCreateStruct(
2601
            'no-fields-type'
2602
        );
2603
        $typeCreateStruct->remoteId = 'new-unique-remoteid';
2604
        $typeCreateStruct->creatorId = $repository->getPermissionResolver()->getCurrentUserReference()->getUserId();
2605
        $typeCreateStruct->creationDate = new \DateTime();
2606
        $typeCreateStruct->mainLanguageCode = 'eng-US';
2607
        $typeCreateStruct->names = ['eng-US' => 'A name.'];
2608
        $typeCreateStruct->descriptions = ['eng-US' => 'A description.'];
2609
2610
        $contentTypeDraft = $contentTypeService->createContentType(
2611
            $typeCreateStruct,
2612
            [
2613
                $contentTypeService->loadContentTypeGroupByIdentifier('Content'),
2614
            ]
2615
        );
2616
        // Throws an exception because Content Type draft should have at least one field definition.
2617
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
2618
    }
2619
2620
    /**
2621
     * Test for the loadContentType() method.
2622
     *
2623
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentType()
2624
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
2625
     * @group user
2626
     * @group field-type
2627
     */
2628
    public function testLoadContentType()
2629
    {
2630
        $repository = $this->getRepository();
2631
2632
        $userGroupId = $this->generateId('type', 3);
2633
        /* BEGIN: Use Case */
2634
        // $userGroupId is the ID of the "user_group" type
2635
        $contentTypeService = $repository->getContentTypeService();
2636
        // Loads the standard "user_group" type
2637
        $userGroupType = $contentTypeService->loadContentType($userGroupId);
2638
        /* END: Use Case */
2639
2640
        $this->assertInstanceOf(
2641
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType',
2642
            $userGroupType
2643
        );
2644
2645
        return $userGroupType;
2646
    }
2647
2648
    /**
2649
     * Test that multi-language logic respects prioritized language list.
2650
     *
2651
     * @dataProvider getPrioritizedLanguageList
2652
     *
2653
     * @param string[] $languageCodes
2654
     */
2655
    public function testLoadContentTypeWithPrioritizedLanguagesList(array $languageCodes)
2656
    {
2657
        $repository = $this->getRepository();
2658
        $contentTypeService = $repository->getContentTypeService();
2659
2660
        $contentType = $this->createContentTypeDraft();
2661
        $contentTypeService->publishContentTypeDraft($contentType);
2662
        $contentType = $contentTypeService->loadContentType($contentType->id, $languageCodes);
2663
2664
        $language = isset($languageCodes[0]) ? $languageCodes[0] : 'eng-US';
2665
        /** @var \eZ\Publish\Core\FieldType\TextLine\Value $nameValue */
2666
        self::assertEquals(
2667
            $contentType->getName($language),
2668
            $contentType->getName()
2669
        );
2670
        self::assertEquals(
2671
            $contentType->getDescription($language),
2672
            $contentType->getDescription()
2673
        );
2674
2675
        foreach ($contentType->getFieldDefinitions() as $fieldDefinition) {
2676
            self::assertEquals(
2677
                $fieldDefinition->getName($language),
2678
                $fieldDefinition->getName()
2679
            );
2680
            self::assertEquals(
2681
                $fieldDefinition->getDescription($language),
2682
                $fieldDefinition->getDescription()
2683
            );
2684
        }
2685
    }
2686
2687
    /**
2688
     * @return array
2689
     */
2690
    public function getPrioritizedLanguageList()
2691
    {
2692
        return [
2693
            [[]],
2694
            [['eng-US']],
2695
            [['ger-DE']],
2696
            [['eng-US', 'ger-DE']],
2697
            [['ger-DE', 'eng-US']],
2698
        ];
2699
    }
2700
2701
    /**
2702
     * Test for the loadContentType() method.
2703
     *
2704
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentType()
2705
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentType
2706
     */
2707
    public function testLoadContentTypeStructValues($userGroupType)
2708
    {
2709
        $repository = $this->getRepository();
2710
        $contentTypeService = $repository->getContentTypeService();
2711
2712
        $this->assertPropertiesCorrect(
2713
            [
2714
                'id' => $this->generateId('type', 3),
2715
                'status' => 0,
2716
                'identifier' => 'user_group',
2717
                'creationDate' => $this->createDateTime(1024392098),
2718
                'modificationDate' => $this->createDateTime(1048494743),
2719
                'creatorId' => $this->generateId('user', 14),
2720
                'modifierId' => $this->generateId('user', 14),
2721
                'remoteId' => '25b4268cdcd01921b808a0d854b877ef',
2722
                'names' => [
2723
                    'eng-US' => 'User group',
2724
                ],
2725
                'descriptions' => [],
2726
                'nameSchema' => '<name>',
2727
                'isContainer' => true,
2728
                'mainLanguageCode' => 'eng-US',
2729
                'defaultAlwaysAvailable' => true,
2730
                'defaultSortField' => 1,
2731
                'defaultSortOrder' => 1,
2732
                'contentTypeGroups' => [
2733
                    0 => $contentTypeService->loadContentTypeGroup($this->generateId('typegroup', 2)),
2734
                ],
2735
            ],
2736
            $userGroupType
2737
        );
2738
2739
        return $userGroupType->fieldDefinitions;
2740
    }
2741
2742
    /**
2743
     * Test for the loadContentType() method.
2744
     *
2745
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentType()
2746
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeStructValues
2747
     */
2748
    public function testLoadContentTypeFieldDefinitions(APIFieldDefinitionCollection $fieldDefinitions)
2749
    {
2750
        $expectedFieldDefinitions = [
2751
            'name' => [
2752
                'identifier' => 'name',
2753
                'fieldGroup' => '',
2754
                'position' => 1,
2755
                'fieldTypeIdentifier' => 'ezstring',
2756
                'isTranslatable' => true,
2757
                'isRequired' => true,
2758
                'isInfoCollector' => false,
2759
                'isSearchable' => true,
2760
                'defaultValue' => new TextLineValue(),
2761
                'names' => [
2762
                    'eng-US' => 'Name',
2763
                ],
2764
                'descriptions' => [],
2765
            ],
2766
            'description' => [
2767
                'identifier' => 'description',
2768
                'fieldGroup' => '',
2769
                'position' => 2,
2770
                'fieldTypeIdentifier' => 'ezstring',
2771
                'isTranslatable' => true,
2772
                'isRequired' => false,
2773
                'isInfoCollector' => false,
2774
                'isSearchable' => true,
2775
                'defaultValue' => new TextLineValue(),
2776
                'names' => [
2777
                    'eng-US' => 'Description',
2778
                ],
2779
                'descriptions' => [],
2780
            ],
2781
        ];
2782
2783
        $fieldDefinitions = $fieldDefinitions->toArray();
2784
        foreach ($fieldDefinitions as $index => $fieldDefinition) {
2785
            $this->assertInstanceOf(
2786
                'eZ\\Publish\\API\\Repository\\Values\\ContentType\\FieldDefinition',
2787
                $fieldDefinition
2788
            );
2789
2790
            $this->assertNotNull($fieldDefinition->id);
2791
2792
            if (!isset($expectedFieldDefinitions[$fieldDefinition->identifier])) {
2793
                $this->fail(
2794
                    sprintf(
2795
                        'Unexpected Field definition loaded: "%s" (%s)',
2796
                        $fieldDefinition->identifier,
2797
                        $fieldDefinition->id
2798
                    )
2799
                );
2800
            }
2801
2802
            $this->assertPropertiesCorrect(
2803
                $expectedFieldDefinitions[$fieldDefinition->identifier],
2804
                $fieldDefinition
2805
            );
2806
            unset($expectedFieldDefinitions[$fieldDefinition->identifier]);
2807
            unset($fieldDefinitions[$index]);
2808
        }
2809
2810
        if (0 !== count($expectedFieldDefinitions)) {
2811
            $this->fail(
2812
                sprintf(
2813
                    'Missing expected Field definitions: %s',
2814
                    implode(',', array_column($expectedFieldDefinitions, 'identifier'))
2815
                )
2816
            );
2817
        }
2818
2819
        if (0 !== count($fieldDefinitions)) {
2820
            $this->fail(
2821
                sprintf(
2822
                    'Loaded unexpected Field definitions: %s',
2823
                    implode(
2824
                        ',',
2825
                        array_map(
2826
                            function ($fieldDefinition) {
2827
                                return $fieldDefinition->identifier;
2828
                            },
2829
                            $fieldDefinitions
2830
                        )
2831
                    )
2832
                )
2833
            );
2834
        }
2835
    }
2836
2837
    /**
2838
     * Test for the loadContentType() method.
2839
     *
2840
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentType()
2841
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentType
2842
     */
2843
    public function testLoadContentTypeThrowsNotFoundException()
2844
    {
2845
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2846
2847
        $repository = $this->getRepository();
2848
2849
        $nonExistentTypeId = $this->generateId('type', 2342);
2850
        /* BEGIN: Use Case */
2851
        $contentTypeService = $repository->getContentTypeService();
2852
2853
        // Throws exception, since type with ID 2342 does not exist
2854
        $contentTypeService->loadContentType($nonExistentTypeId);
2855
        /* END: Use Case */
2856
    }
2857
2858
    /**
2859
     * Test for the loadContentTypeByIdentifier() method.
2860
     *
2861
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
2862
     *
2863
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeByIdentifier()
2864
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentType
2865
     * @group user
2866
     */
2867
    public function testLoadContentTypeByIdentifier()
2868
    {
2869
        $repository = $this->getRepository();
2870
2871
        /* BEGIN: Use Case */
2872
        $contentTypeService = $repository->getContentTypeService();
2873
2874
        $articleType = $contentTypeService->loadContentTypeByIdentifier('article');
2875
        /* END: Use Case */
2876
2877
        $this->assertInstanceOf(
2878
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType',
2879
            $articleType
2880
        );
2881
2882
        return $articleType;
2883
    }
2884
2885
    /**
2886
     * Test for the loadContentTypeByIdentifier() method.
2887
     *
2888
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType
2889
     *
2890
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeByIdentifier()
2891
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
2892
     */
2893
    public function testLoadContentTypeByIdentifierReturnsCorrectInstance($contentType)
2894
    {
2895
        $repository = $this->getRepository();
2896
        $contentTypeService = $repository->getContentTypeService();
2897
2898
        $this->assertEquals(
2899
            $contentTypeService->loadContentType($contentType->id),
2900
            $contentType
2901
        );
2902
    }
2903
2904
    /**
2905
     * Test for the loadContentTypeByIdentifier() method.
2906
     *
2907
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeByIdentifier()
2908
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
2909
     */
2910
    public function testLoadContentTypeByIdentifierThrowsNotFoundException()
2911
    {
2912
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2913
2914
        $repository = $this->getRepository();
2915
2916
        /* BEGIN: Use Case */
2917
        $contentTypeService = $repository->getContentTypeService();
2918
2919
        // Throws an exception, since no type with this identifier exists
2920
        $contentTypeService->loadContentTypeByIdentifier('sindelfingen');
2921
        /* END: Use Case */
2922
    }
2923
2924
    /**
2925
     * Test for the loadContentTypeByRemoteId() method.
2926
     *
2927
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeByRemoteId()
2928
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentType
2929
     */
2930
    public function testLoadContentTypeByRemoteId()
2931
    {
2932
        $repository = $this->getRepository();
2933
2934
        /* BEGIN: Use Case */
2935
        $contentTypeService = $repository->getContentTypeService();
2936
2937
        // Loads the standard "user_group" type
2938
        $userGroupType = $contentTypeService->loadContentTypeByRemoteId(
2939
            '25b4268cdcd01921b808a0d854b877ef'
2940
        );
2941
        /* END: Use Case */
2942
2943
        $this->assertInstanceOf(
2944
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType',
2945
            $userGroupType
2946
        );
2947
2948
        return $userGroupType;
2949
    }
2950
2951
    /**
2952
     * Test for the loadContentTypeByRemoteId() method.
2953
     *
2954
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeByRemoteId()
2955
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByRemoteId
2956
     */
2957
    public function testLoadContentTypeByRemoteIdReturnsCorrectInstance($contentType)
2958
    {
2959
        $repository = $this->getRepository();
2960
        $contentTypeService = $repository->getContentTypeService();
2961
2962
        $this->assertEquals(
2963
            $contentTypeService->loadContentType($contentType->id),
2964
            $contentType
2965
        );
2966
    }
2967
2968
    /**
2969
     * Test for the loadContentTypeByRemoteId() method.
2970
     *
2971
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeByRemoteId()
2972
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentType
2973
     */
2974
    public function testLoadContentTypeByRemoteIdThrowsNotFoundException()
2975
    {
2976
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2977
2978
        $repository = $this->getRepository();
2979
2980
        /* BEGIN: Use Case */
2981
        $contentTypeService = $repository->getContentTypeService();
2982
2983
        // Throws an exception, since no type with this remote ID exists
2984
        $contentTypeService->loadContentTypeByRemoteId('not-exists');
2985
        /* END: Use Case */
2986
    }
2987
2988
    /**
2989
     * Test for the loadContentTypeList() method.
2990
     *
2991
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypeList()
2992
     * @depends testLoadContentType
2993
     */
2994
    public function testLoadContentTypeList()
2995
    {
2996
        $repository = $this->getRepository();
2997
        $contentTypeService = $repository->getContentTypeService();
2998
2999
        $types = $contentTypeService->loadContentTypeList([3, 4]);
3000
3001
        $this->assertIsIterable($types);
3002
3003
        $this->assertEquals(
3004
            [
3005
                3 => $contentTypeService->loadContentType(3),
3006
                4 => $contentTypeService->loadContentType(4),
3007
            ],
3008
            $types
3009
        );
3010
    }
3011
3012
    /**
3013
     * Test for the loadContentTypes() method.
3014
     *
3015
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypes()
3016
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentType
3017
     */
3018
    public function testLoadContentTypes()
3019
    {
3020
        $repository = $this->getRepository();
3021
3022
        $typeGroupId = $this->generateId('typegroup', 2);
3023
        /* BEGIN: Use Case */
3024
        // $typeGroupId is a valid ID of a content type group
3025
        $contentTypeService = $repository->getContentTypeService();
3026
3027
        $contentTypeGroup = $contentTypeService->loadContentTypeGroup($typeGroupId);
3028
3029
        // Loads all types from content type group "Users"
3030
        $types = $contentTypeService->loadContentTypes($contentTypeGroup);
3031
        /* END: Use Case */
3032
3033
        $this->assertIsArray($types);
3034
3035
        return $types;
3036
    }
3037
3038
    /**
3039
     * Test for the loadContentTypes() method.
3040
     *
3041
     * @see \eZ\Publish\API\Repository\ContentTypeService::loadContentTypes()
3042
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypes
3043
     */
3044
    public function testLoadContentTypesContent(array $types)
3045
    {
3046
        $repository = $this->getRepository();
3047
        $contentTypeService = $repository->getContentTypeService();
3048
3049
        usort(
3050
            $types,
3051
            function ($a, $b) {
3052
                if ($a->id == $b->id) {
3053
                    return 0;
3054
                }
3055
3056
                return ($a->id < $b->id) ? -1 : 1;
3057
            }
3058
        );
3059
        $this->assertEquals(
3060
            [
3061
                $contentTypeService->loadContentType($this->generateId('type', 3)),
3062
                $contentTypeService->loadContentType($this->generateId('type', 4)),
3063
            ],
3064
            $types
3065
        );
3066
    }
3067
3068
    /**
3069
     * Test for the createContentTypeDraft() method.
3070
     *
3071
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeDraft()
3072
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentType
3073
     */
3074
    public function testCreateContentTypeDraft()
3075
    {
3076
        $repository = $this->getRepository();
3077
3078
        /* BEGIN: Use Case */
3079
        $contentTypeService = $repository->getContentTypeService();
3080
3081
        $commentType = $contentTypeService->loadContentTypeByIdentifier('comment', Language::ALL);
3082
3083
        $commentTypeDraft = $contentTypeService->createContentTypeDraft($commentType);
3084
        /* END: Use Case */
3085
3086
        $this->assertInstanceOf(
3087
            'eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentTypeDraft',
3088
            $commentTypeDraft
3089
        );
3090
3091
        return [
3092
            'originalType' => $commentType,
3093
            'typeDraft' => $commentTypeDraft,
3094
        ];
3095
    }
3096
3097
    /**
3098
     * Test for the createContentTypeDraft() method.
3099
     *
3100
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeDraft()
3101
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeDraft
3102
     */
3103
    public function testCreateContentTypeDraftStructValues(array $data)
3104
    {
3105
        $originalType = $data['originalType'];
3106
        $typeDraft = $data['typeDraft'];
3107
3108
        // Names and descriptions tested in corresponding language test
3109
        $this->assertPropertiesCorrect(
3110
            [
3111
                'id' => $originalType->id,
3112
                'names' => $originalType->names,
3113
                'descriptions' => $originalType->descriptions,
3114
                'identifier' => $originalType->identifier,
3115
                'creatorId' => $originalType->creatorId,
3116
                'modifierId' => $originalType->modifierId,
3117
                'remoteId' => $originalType->remoteId,
3118
                'urlAliasSchema' => $originalType->urlAliasSchema,
3119
                'nameSchema' => $originalType->nameSchema,
3120
                'isContainer' => $originalType->isContainer,
3121
                'mainLanguageCode' => $originalType->mainLanguageCode,
3122
                'defaultAlwaysAvailable' => $originalType->defaultAlwaysAvailable,
3123
                'defaultSortField' => $originalType->defaultSortField,
3124
                'defaultSortOrder' => $originalType->defaultSortOrder,
3125
                'contentTypeGroups' => $originalType->contentTypeGroups,
3126
                'fieldDefinitions' => $originalType->fieldDefinitions,
3127
            ],
3128
            $typeDraft
3129
        );
3130
3131
        $this->assertInstanceOf(
3132
            'DateTime',
3133
            $typeDraft->modificationDate
3134
        );
3135
        $modificationDifference = $originalType->modificationDate->diff(
3136
            $typeDraft->modificationDate
3137
        );
3138
        // No modification date is newer, interval is not inverted
3139
        $this->assertEquals(0, $modificationDifference->invert);
3140
3141
        $this->assertEquals(
3142
            ContentType::STATUS_DRAFT,
3143
            $typeDraft->status
3144
        );
3145
3146
        return $data;
3147
    }
3148
3149
    /**
3150
     * Test for the createContentTypeDraft() method.
3151
     *
3152
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeDraft()
3153
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeDraftStructValues
3154
     */
3155
    public function testCreateContentTypeDraftStructLanguageDependentValues(array $data)
3156
    {
3157
        $originalType = $data['originalType'];
3158
        $typeDraft = $data['typeDraft'];
3159
3160
        $this->assertEquals(
3161
            [
3162
                'names' => $originalType->names,
3163
                'descriptions' => $originalType->descriptions,
3164
            ],
3165
            [
3166
                'names' => $typeDraft->names,
3167
                'descriptions' => $typeDraft->descriptions,
3168
            ]
3169
        );
3170
    }
3171
3172
    /**
3173
     * Test for the createContentTypeDraft() method.
3174
     *
3175
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeDraft()
3176
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeDraft
3177
     */
3178 View Code Duplication
    public function testCreateContentTypeDraftThrowsBadStateException()
3179
    {
3180
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
3181
3182
        $repository = $this->getRepository();
3183
3184
        /* BEGIN: Use Case */
3185
        $contentTypeService = $repository->getContentTypeService();
3186
3187
        $commentType = $contentTypeService->loadContentTypeByIdentifier('comment');
3188
3189
        $contentTypeService->createContentTypeDraft($commentType);
3190
3191
        // Throws exception, since type draft already exists
3192
        $contentTypeService->createContentTypeDraft($commentType);
3193
        /* END: Use Case */
3194
    }
3195
3196
    /**
3197
     * Test for the deleteContentType() method.
3198
     *
3199
     * @covers \eZ\Publish\API\Repository\ContentTypeService::deleteContentType()
3200
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
3201
     */
3202
    public function testDeleteContentType()
3203
    {
3204
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
3205
3206
        $repository = $this->getRepository();
3207
3208
        /* BEGIN: Use Case */
3209
        $contentTypeService = $repository->getContentTypeService();
3210
3211
        $commentType = $contentTypeService->loadContentTypeByIdentifier('comment');
3212
3213
        $contentTypeService->deleteContentType($commentType);
3214
        /* END: Use Case */
3215
3216
        $contentTypeService->loadContentType($commentType->id);
3217
        $this->fail('Content type could be loaded after delete.');
3218
    }
3219
3220
    /**
3221
     * Test for the deleteContentType() method.
3222
     *
3223
     * @see \eZ\Publish\API\Repository\ContentTypeService::deleteContentType()
3224
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testDeleteContentType
3225
     */
3226 View Code Duplication
    public function testDeleteContentTypeThrowsBadStateException()
3227
    {
3228
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
3229
3230
        $repository = $this->getRepository();
3231
3232
        /* BEGIN: Use Case */
3233
        $contentTypeService = $repository->getContentTypeService();
3234
3235
        $contentType = $contentTypeService->loadContentTypeByIdentifier('user');
3236
3237
        // This call will fail with a "BadStateException" because there is at
3238
        // least on content object of type "user" in an eZ Publish demo
3239
        $contentTypeService->deleteContentType($contentType);
3240
        /* END: Use Case */
3241
    }
3242
3243
    /**
3244
     * Test for the copyContentType() method.
3245
     *
3246
     * @return array
3247
     *
3248
     * @see \eZ\Publish\API\Repository\ContentTypeService::copyContentType()
3249
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
3250
     */
3251
    public function testCopyContentType()
3252
    {
3253
        $repository = $this->getRepository();
3254
3255
        /* BEGIN: Use Case */
3256
        $contentTypeService = $repository->getContentTypeService();
3257
3258
        $commentType = $contentTypeService->loadContentTypeByIdentifier('comment');
3259
3260
        // Complete copy of the "comment" type
3261
        $copiedType = $contentTypeService->copyContentType($commentType);
3262
        /* END: Use Case */
3263
3264
        $this->assertInstanceOf(
3265
            '\\eZ\\Publish\\API\\Repository\\Values\\ContentType\\ContentType',
3266
            $copiedType
3267
        );
3268
3269
        return [
3270
            'originalType' => $commentType,
3271
            'copiedType' => $copiedType,
3272
        ];
3273
    }
3274
3275
    /**
3276
     * Test for the copyContentType() method.
3277
     *
3278
     * @param array $data
3279
     *
3280
     * @see \eZ\Publish\API\Repository\ContentTypeService::copyContentType()
3281
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCopyContentType
3282
     */
3283
    public function testCopyContentTypeStructValues(array $data)
3284
    {
3285
        $originalType = $data['originalType'];
3286
        $copiedType = $data['copiedType'];
3287
3288
        $this->assertCopyContentTypeValues($originalType, $copiedType);
3289
    }
3290
3291
    /**
3292
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $originalType
3293
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $copiedType
3294
     * @param array $excludedProperties
3295
     */
3296
    private function assertCopyContentTypeValues($originalType, $copiedType, $excludedProperties = [])
3297
    {
3298
        $allProperties = [
3299
            'names',
3300
            'descriptions',
3301
            'creatorId',
3302
            'modifierId',
3303
            'urlAliasSchema',
3304
            'nameSchema',
3305
            'isContainer',
3306
            'mainLanguageCode',
3307
            'contentTypeGroups',
3308
        ];
3309
        $properties = array_diff($allProperties, $excludedProperties);
3310
        $this->assertStructPropertiesCorrect(
3311
            $originalType,
3312
            $copiedType,
3313
            $properties
3314
        );
3315
3316
        $this->assertNotEquals(
3317
            $originalType->id,
3318
            $copiedType->id
3319
        );
3320
        $this->assertNotEquals(
3321
            $originalType->remoteId,
3322
            $copiedType->remoteId
3323
        );
3324
        $this->assertNotEquals(
3325
            $originalType->identifier,
3326
            $copiedType->identifier
3327
        );
3328
        $this->assertNotEquals(
3329
            $originalType->creationDate,
3330
            $copiedType->creationDate
3331
        );
3332
        $this->assertNotEquals(
3333
            $originalType->modificationDate,
3334
            $copiedType->modificationDate
3335
        );
3336
3337
        foreach ($originalType->fieldDefinitions as $originalFieldDefinition) {
3338
            $copiedFieldDefinition = $copiedType->getFieldDefinition(
3339
                $originalFieldDefinition->identifier
3340
            );
3341
3342
            $this->assertStructPropertiesCorrect(
3343
                $originalFieldDefinition,
3344
                $copiedFieldDefinition,
0 ignored issues
show
Bug introduced by
It seems like $copiedFieldDefinition defined by $copiedType->getFieldDef...Definition->identifier) on line 3338 can be null; however, eZ\Publish\API\Repositor...ructPropertiesCorrect() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
3345
                [
3346
                    'identifier',
3347
                    'names',
3348
                    'descriptions',
3349
                    'fieldGroup',
3350
                    'position',
3351
                    'fieldTypeIdentifier',
3352
                    'isTranslatable',
3353
                    'isRequired',
3354
                    'isInfoCollector',
3355
                    'validatorConfiguration',
3356
                    'defaultValue',
3357
                    'isSearchable',
3358
                ]
3359
            );
3360
            $this->assertNotEquals(
3361
                $originalFieldDefinition->id,
3362
                $copiedFieldDefinition->id
3363
            );
3364
        }
3365
    }
3366
3367
    /**
3368
     * Test for the copyContentType() method.
3369
     *
3370
     * @see \eZ\Publish\API\Repository\ContentTypeService::copyContentType($contentType, $user)
3371
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCopyContentType
3372
     */
3373
    public function testCopyContentTypeWithSecondParameter()
3374
    {
3375
        $repository = $this->getRepository();
3376
3377
        /* BEGIN: Use Case */
3378
        $contentTypeService = $repository->getContentTypeService();
3379
3380
        $user = $this->createUserVersion1();
3381
3382
        $commentType = $contentTypeService->loadContentTypeByIdentifier('comment');
3383
3384
        // Complete copy of the "comment" type
3385
        $copiedType = $contentTypeService->copyContentType($commentType, $user);
3386
        /* END: Use Case */
3387
3388
        $this->assertPropertiesCorrect(
3389
            [
3390
                'creatorId' => $user->id,
3391
                'modifierId' => $user->id,
3392
            ],
3393
            $copiedType
3394
        );
3395
        $this->assertCopyContentTypeValues($commentType, $copiedType, ['creatorId', 'modifierId']);
3396
    }
3397
3398
    /**
3399
     * Test for the assignContentTypeGroup() method.
3400
     *
3401
     * @see \eZ\Publish\API\Repository\ContentTypeService::assignContentTypeGroup()
3402
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroupByIdentifier
3403
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
3404
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentType
3405
     */
3406
    public function testAssignContentTypeGroup()
3407
    {
3408
        $repository = $this->getRepository();
3409
3410
        /* BEGIN: Use Case */
3411
        $contentTypeService = $repository->getContentTypeService();
3412
3413
        $mediaGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Media');
3414
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
3415
3416
        $contentTypeService->assignContentTypeGroup($folderType, $mediaGroup);
3417
        /* END: Use Case */
3418
3419
        $loadedType = $contentTypeService->loadContentType($folderType->id);
3420
3421
        foreach ($loadedType->contentTypeGroups as $loadedGroup) {
3422
            if ($mediaGroup->id == $loadedGroup->id) {
3423
                return;
3424
            }
3425
        }
3426
        $this->fail(
3427
            sprintf(
3428
                'Group with ID "%s" not assigned to Content Type.',
3429
                $mediaGroup->id
3430
            )
3431
        );
3432
    }
3433
3434
    /**
3435
     * Test for the assignContentTypeGroup() method.
3436
     *
3437
     * @see \eZ\Publish\API\Repository\ContentTypeService::assignContentTypeGroup()
3438
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAssignContentTypeGroup
3439
     */
3440 View Code Duplication
    public function testAssignContentTypeGroupThrowsInvalidArgumentException()
3441
    {
3442
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
3443
3444
        $repository = $this->getRepository();
3445
3446
        /* BEGIN: Use Case */
3447
        $contentTypeService = $repository->getContentTypeService();
3448
3449
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
3450
        $assignedGroups = $folderType->contentTypeGroups;
3451
3452
        foreach ($assignedGroups as $assignedGroup) {
3453
            // Throws an exception, since group is already assigned
3454
            $contentTypeService->assignContentTypeGroup($folderType, $assignedGroup);
3455
        }
3456
        /* END: Use Case */
3457
    }
3458
3459
    /**
3460
     * Test for the unassignContentTypeGroup() method.
3461
     *
3462
     * @see \eZ\Publish\API\Repository\ContentTypeService::unassignContentTypeGroup()
3463
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAssignContentTypeGroup
3464
     */
3465
    public function testUnassignContentTypeGroup()
3466
    {
3467
        $repository = $this->getRepository();
3468
3469
        /* BEGIN: Use Case */
3470
        $contentTypeService = $repository->getContentTypeService();
3471
3472
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
3473
3474
        $mediaGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Media');
3475
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
3476
3477
        // May not unassign last group
3478
        $contentTypeService->assignContentTypeGroup($folderType, $mediaGroup);
3479
3480
        $contentTypeService->unassignContentTypeGroup($folderType, $contentGroup);
3481
        /* END: Use Case */
3482
3483
        $loadedType = $contentTypeService->loadContentType($folderType->id);
3484
3485
        foreach ($loadedType->contentTypeGroups as $assignedGroup) {
3486
            if ($assignedGroup->id == $contentGroup->id) {
3487
                $this->fail(
3488
                    sprintf(
3489
                        'Could not unassign group with ID "%s".',
3490
                        $assignedGroup->id
3491
                    )
3492
                );
3493
            }
3494
        }
3495
    }
3496
3497
    /**
3498
     * Test for the unassignContentTypeGroup() method.
3499
     *
3500
     * @see \eZ\Publish\API\Repository\ContentTypeService::unassignContentTypeGroup()
3501
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUnassignContentTypeGroup
3502
     */
3503 View Code Duplication
    public function testUnassignContentTypeGroupThrowsInvalidArgumentException()
3504
    {
3505
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
3506
3507
        $repository = $this->getRepository();
3508
3509
        /* BEGIN: Use Case */
3510
        $contentTypeService = $repository->getContentTypeService();
3511
3512
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
3513
        $notAssignedGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Media');
3514
3515
        // Throws an exception, since "Media" group is not assigned to "folder"
3516
        $contentTypeService->unassignContentTypeGroup($folderType, $notAssignedGroup);
3517
        /* END: Use Case */
3518
    }
3519
3520
    /**
3521
     * Test for the unassignContentTypeGroup() method.
3522
     *
3523
     * @see \eZ\Publish\API\Repository\ContentTypeService::unassignContentTypeGroup()
3524
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUnassignContentTypeGroup
3525
     */
3526 View Code Duplication
    public function testUnassignContentTypeGroupThrowsBadStateException()
3527
    {
3528
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
3529
3530
        $repository = $this->getRepository();
3531
3532
        /* BEGIN: Use Case */
3533
        $contentTypeService = $repository->getContentTypeService();
3534
3535
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
3536
        $assignedGroups = $folderType->contentTypeGroups;
3537
3538
        foreach ($assignedGroups as $assignedGroup) {
3539
            // Throws an exception, when last group is to be removed
3540
            $contentTypeService->unassignContentTypeGroup($folderType, $assignedGroup);
3541
        }
3542
        /* END: Use Case */
3543
    }
3544
3545
    /**
3546
     * Test for the createContentTypeGroup() method.
3547
     *
3548
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeGroup()
3549
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroup
3550
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeGroup
3551
     */
3552 View Code Duplication
    public function testCreateContentTypeGroupInTransactionWithRollback()
3553
    {
3554
        $repository = $this->getRepository();
3555
3556
        /* BEGIN: Use Case */
3557
        $contentTypeService = $repository->getContentTypeService();
3558
3559
        // Get create struct and set language property
3560
        $groupCreate = $contentTypeService->newContentTypeGroupCreateStruct('new-group');
3561
        /* @todo uncomment when support for multilingual names and descriptions is added
3562
        $groupCreate->mainLanguageCode = 'eng-GB';
3563
        */
3564
3565
        // Start a new transaction
3566
        $repository->beginTransaction();
3567
3568
        try {
3569
            // Create the new content type group
3570
            $groupId = $contentTypeService->createContentTypeGroup($groupCreate)->id;
3571
        } catch (Exception $e) {
3572
            // Cleanup hanging transaction on error
3573
            $repository->rollback();
3574
            throw $e;
3575
        }
3576
3577
        // Rollback all changes
3578
        $repository->rollback();
3579
3580
        try {
3581
            // This call will fail with a "NotFoundException"
3582
            $contentTypeService->loadContentTypeGroup($groupId);
3583
        } catch (NotFoundException $e) {
3584
            return;
3585
        }
3586
        /* END: Use Case */
3587
3588
        $this->fail('Can still load content type group after rollback');
3589
    }
3590
3591
    /**
3592
     * Test for the createContentTypeGroup() method.
3593
     *
3594
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentTypeGroup()
3595
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroup
3596
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentTypeGroup
3597
     */
3598 View Code Duplication
    public function testCreateContentTypeGroupInTransactionWithCommit()
3599
    {
3600
        $repository = $this->getRepository();
3601
3602
        /* BEGIN: Use Case */
3603
        $contentTypeService = $repository->getContentTypeService();
3604
3605
        // Get create struct and set language property
3606
        $groupCreate = $contentTypeService->newContentTypeGroupCreateStruct('new-group');
3607
        /* @todo uncomment when support for multilingual names and descriptions is added
3608
        $groupCreate->mainLanguageCode = 'eng-GB';
3609
        */
3610
3611
        // Start a new transaction
3612
        $repository->beginTransaction();
3613
3614
        try {
3615
            // Create the new content type group
3616
            $groupId = $contentTypeService->createContentTypeGroup($groupCreate)->id;
3617
3618
            // Rollback all changes
3619
            $repository->commit();
3620
        } catch (Exception $e) {
3621
            // Cleanup hanging transaction on error
3622
            $repository->rollback();
3623
            throw $e;
3624
        }
3625
3626
        // Load created content type group
3627
        $group = $contentTypeService->loadContentTypeGroup($groupId);
3628
        /* END: Use Case */
3629
3630
        $this->assertEquals($groupId, $group->id);
3631
    }
3632
3633
    /**
3634
     * Test for the updateContentTypeGroup() method.
3635
     *
3636
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeGroup()
3637
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeGroup
3638
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroupByIdentifier
3639
     */
3640
    public function testUpdateContentTypeGroupInTransactionWithRollback()
3641
    {
3642
        $repository = $this->getRepository();
3643
3644
        /* BEGIN: Use Case */
3645
        $contentTypeService = $repository->getContentTypeService();
3646
3647
        // Load an existing group
3648
        $group = $contentTypeService->loadContentTypeGroupByIdentifier('Setup');
3649
3650
        // Get an update struct and change the identifier
3651
        $groupUpdate = $contentTypeService->newContentTypeGroupUpdateStruct();
3652
        $groupUpdate->identifier = 'Teardown';
3653
3654
        // Start a new transaction
3655
        $repository->beginTransaction();
3656
3657
        try {
3658
            // Apply update to group
3659
            $contentTypeService->updateContentTypeGroup($group, $groupUpdate);
3660
        } catch (Exception $e) {
3661
            // Cleanup hanging transaction on error
3662
            $repository->rollback();
3663
            throw $e;
3664
        }
3665
3666
        // Rollback all changes
3667
        $repository->rollback();
3668
3669
        // Load updated group, it will be unchanged
3670
        $updatedGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Setup');
3671
        /* END: Use Case */
3672
3673
        $this->assertEquals('Setup', $updatedGroup->identifier);
3674
    }
3675
3676
    /**
3677
     * Test for the updateContentTypeGroup() method.
3678
     *
3679
     * @see \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeGroup()
3680
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testUpdateContentTypeGroup
3681
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroupByIdentifier
3682
     */
3683
    public function testUpdateContentTypeGroupInTransactionWithCommit()
3684
    {
3685
        $repository = $this->getRepository();
3686
3687
        /* BEGIN: Use Case */
3688
        $contentTypeService = $repository->getContentTypeService();
3689
3690
        // Load an existing group
3691
        $group = $contentTypeService->loadContentTypeGroupByIdentifier('Setup');
3692
3693
        // Get an update struct and change the identifier
3694
        $groupUpdate = $contentTypeService->newContentTypeGroupUpdateStruct();
3695
        $groupUpdate->identifier = 'Teardown';
3696
3697
        // Start a new transaction
3698
        $repository->beginTransaction();
3699
3700
        try {
3701
            // Apply update to group
3702
            $contentTypeService->updateContentTypeGroup($group, $groupUpdate);
3703
3704
            // Commit all changes
3705
            $repository->commit();
3706
        } catch (Exception $e) {
3707
            // Cleanup hanging transaction on error
3708
            $repository->rollback();
3709
            throw $e;
3710
        }
3711
3712
        // Load updated group by it's new identifier "Teardown"
3713
        $updatedGroup = $contentTypeService->loadContentTypeGroupByIdentifier(
3714
            'Teardown'
3715
        );
3716
        /* END: Use Case */
3717
3718
        $this->assertEquals('Teardown', $updatedGroup->identifier);
3719
    }
3720
3721
    /**
3722
     * Test for the deleteContentTypeGroup() method.
3723
     *
3724
     * @see \eZ\Publish\API\Repository\ContentTypeService::deleteContentTypeGroup()
3725
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testDeleteContentTypeGroup
3726
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroupByIdentifierThrowsNotFoundException
3727
     */
3728 View Code Duplication
    public function testDeleteContentTypeGroupWithRollback()
3729
    {
3730
        $repository = $this->getRepository();
3731
3732
        /* BEGIN: Use Case */
3733
        $contentTypeService = $repository->getContentTypeService();
3734
3735
        // Get a group create struct
3736
        $groupCreate = $contentTypeService->newContentTypeGroupCreateStruct(
3737
            'new-group'
3738
        );
3739
3740
        // Start a new transaction
3741
        $repository->beginTransaction();
3742
3743
        try {
3744
            // Create the new group
3745
            $group = $contentTypeService->createContentTypeGroup($groupCreate);
3746
3747
            // Delete the currently created group
3748
            $contentTypeService->deleteContentTypeGroup($group);
3749
        } catch (Exception $e) {
3750
            // Cleanup hanging transaction on error
3751
            $repository->rollback();
3752
            throw $e;
3753
        }
3754
3755
        // Rollback all changes
3756
        $repository->rollback();
3757
3758
        try {
3759
            // This call will fail with an "NotFoundException"
3760
            $contentTypeService->loadContentTypeGroupByIdentifier('new-group');
3761
        } catch (NotFoundException $e) {
3762
            // Expected error path
3763
        }
3764
        /* END: Use Case */
3765
3766
        $this->assertTrue(isset($e), 'Group not deleted after rollback');
3767
    }
3768
3769
    /**
3770
     * Test for the deleteContentTypeGroup() method.
3771
     *
3772
     * @see \eZ\Publish\API\Repository\ContentTypeService::deleteContentTypeGroup()
3773
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testDeleteContentTypeGroup
3774
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeGroupByIdentifierThrowsNotFoundException
3775
     */
3776 View Code Duplication
    public function testDeleteContentTypeGroupWithCommit()
3777
    {
3778
        $repository = $this->getRepository();
3779
3780
        /* BEGIN: Use Case */
3781
        $contentTypeService = $repository->getContentTypeService();
3782
3783
        // Get a group create struct
3784
        $groupCreate = $contentTypeService->newContentTypeGroupCreateStruct(
3785
            'new-group'
3786
        );
3787
3788
        // Start a new transaction
3789
        $repository->beginTransaction();
3790
3791
        try {
3792
            // Create the new group
3793
            $group = $contentTypeService->createContentTypeGroup($groupCreate);
3794
3795
            // Delete the currently created group
3796
            $contentTypeService->deleteContentTypeGroup($group);
3797
3798
            // Commit all changes
3799
            $repository->commit();
3800
        } catch (Exception $e) {
3801
            // Cleanup hanging transaction on error
3802
            $repository->rollback();
3803
            throw $e;
3804
        }
3805
3806
        try {
3807
            // This call will fail with an "NotFoundException"
3808
            $contentTypeService->loadContentTypeGroupByIdentifier('new-group');
3809
        } catch (NotFoundException $e) {
3810
            // Expected error path
3811
        }
3812
        /* END: Use Case */
3813
3814
        $this->assertTrue(isset($e), 'Group not deleted after commit.');
3815
    }
3816
3817
    /**
3818
     * Test for the createContentType() method.
3819
     *
3820
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentType()
3821
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
3822
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifierThrowsNotFoundException
3823
     */
3824
    public function testCreateContentTypeInTransactionWithRollback()
3825
    {
3826
        $repository = $this->getRepository();
3827
3828
        /* BEGIN: Use Case */
3829
        $contentTypeService = $repository->getContentTypeService();
3830
3831
        // Start a new transaction
3832
        $repository->beginTransaction();
3833
3834
        try {
3835
            // Get create struct and set some properties
3836
            $typeCreate = $contentTypeService->newContentTypeCreateStruct('blog-post');
3837
            $typeCreate->mainLanguageCode = 'eng-GB';
3838
            $typeCreate->names = ['eng-GB' => 'Blog post'];
3839
3840
            $titleFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
3841
            $titleFieldCreate->names = ['eng-GB' => 'Title'];
3842
            $titleFieldCreate->position = 1;
3843
            $typeCreate->addFieldDefinition($titleFieldCreate);
3844
3845
            $groups = [
3846
                $contentTypeService->loadContentTypeGroupByIdentifier('Setup'),
3847
            ];
3848
3849
            // Create content type
3850
            $contentTypeDraft = $contentTypeService->createContentType(
3851
                $typeCreate,
3852
                $groups
3853
            );
3854
3855
            // Publish the content type draft
3856
            $contentTypeService->publishContentTypeDraft($contentTypeDraft);
3857
        } catch (Exception $e) {
3858
            // Cleanup hanging transaction on error
3859
            $repository->rollback();
3860
            throw $e;
3861
        }
3862
3863
        // Rollback all changes.
3864
        $repository->rollback();
3865
3866
        try {
3867
            // This call will fail with a "NotFoundException"
3868
            $contentTypeService->loadContentTypeByIdentifier('blog-post');
3869
        } catch (NotFoundException $e) {
3870
            // Expected execution path
3871
        }
3872
        /* END: Use Case */
3873
3874
        $this->assertTrue(isset($e), 'Can still load content type after rollback.');
3875
    }
3876
3877
    /**
3878
     * Test for the createContentType() method.
3879
     *
3880
     * @see \eZ\Publish\API\Repository\ContentTypeService::createContentType()
3881
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCreateContentType
3882
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifierThrowsNotFoundException
3883
     */
3884
    public function testCreateContentTypeInTransactionWithCommit()
3885
    {
3886
        $repository = $this->getRepository();
3887
3888
        /* BEGIN: Use Case */
3889
        $contentTypeService = $repository->getContentTypeService();
3890
3891
        // Start a new transaction
3892
        $repository->beginTransaction();
3893
3894
        try {
3895
            // Get create struct and set some properties
3896
            $typeCreate = $contentTypeService->newContentTypeCreateStruct('blog-post');
3897
            $typeCreate->mainLanguageCode = 'eng-GB';
3898
            $typeCreate->names = ['eng-GB' => 'Blog post'];
3899
3900
            $titleFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
3901
            $titleFieldCreate->names = ['eng-GB' => 'Title'];
3902
            $titleFieldCreate->position = 1;
3903
            $typeCreate->addFieldDefinition($titleFieldCreate);
3904
3905
            $groups = [
3906
                $contentTypeService->loadContentTypeGroupByIdentifier('Setup'),
3907
            ];
3908
3909
            // Create content type
3910
            $contentTypeDraft = $contentTypeService->createContentType(
3911
                $typeCreate,
3912
                $groups
3913
            );
3914
3915
            // Publish the content type draft
3916
            $contentTypeService->publishContentTypeDraft($contentTypeDraft);
3917
3918
            // Commit all changes.
3919
            $repository->commit();
3920
        } catch (Exception $e) {
3921
            // Cleanup hanging transaction on error
3922
            $repository->rollback();
3923
            throw $e;
3924
        }
3925
3926
        // Load the newly created content type
3927
        $contentType = $contentTypeService->loadContentTypeByIdentifier('blog-post');
3928
        /* END: Use Case */
3929
3930
        $this->assertEquals($contentTypeDraft->id, $contentType->id);
3931
    }
3932
3933
    /**
3934
     * Test for the copyContentType() method.
3935
     *
3936
     * @see \eZ\Publish\API\Repository\ContentTypeService::copyContentType()
3937
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCopyContentType
3938
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
3939
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeThrowsNotFoundException
3940
     */
3941 View Code Duplication
    public function testCopyContentTypeInTransactionWithRollback()
3942
    {
3943
        $repository = $this->getRepository();
3944
3945
        /* BEGIN: Use Case */
3946
        $contentTypeService = $repository->getContentTypeService();
3947
3948
        // Load content type to copy
3949
        $contentType = $contentTypeService->loadContentTypeByIdentifier('comment');
3950
3951
        // Start a new transaction
3952
        $repository->beginTransaction();
3953
3954
        try {
3955
            // Complete copy of the content type
3956
            $copiedType = $contentTypeService->copyContentType($contentType);
3957
        } catch (Exception $e) {
3958
            // Cleanup hanging transaction on error
3959
            $repository->rollback();
3960
            throw $e;
3961
        }
3962
3963
        // Rollback all changes
3964
        $repository->rollback();
3965
3966
        try {
3967
            // This call will fail with a "NotFoundException"
3968
            $contentTypeService->loadContentType($copiedType->id);
3969
        } catch (NotFoundException $e) {
3970
            // Expected execution path
3971
        }
3972
        /* END: Use Case */
3973
3974
        $this->assertTrue(isset($e), 'Can still load copied content type after rollback.');
3975
    }
3976
3977
    /**
3978
     * Test for the copyContentType() method.
3979
     *
3980
     * @see \eZ\Publish\API\Repository\ContentTypeService::copyContentType()
3981
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCopyContentType
3982
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
3983
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeThrowsNotFoundException
3984
     */
3985 View Code Duplication
    public function testCopyContentTypeInTransactionWithCommit()
3986
    {
3987
        $repository = $this->getRepository();
3988
3989
        /* BEGIN: Use Case */
3990
        $contentTypeService = $repository->getContentTypeService();
3991
3992
        // Load content type to copy
3993
        $contentType = $contentTypeService->loadContentTypeByIdentifier('comment');
3994
3995
        // Start a new transaction
3996
        $repository->beginTransaction();
3997
3998
        try {
3999
            // Complete copy of the content type
4000
            $contentTypeId = $contentTypeService->copyContentType($contentType)->id;
4001
4002
            // Commit all changes
4003
            $repository->commit();
4004
        } catch (Exception $e) {
4005
            // Cleanup hanging transaction on error
4006
            $repository->rollback();
4007
            throw $e;
4008
        }
4009
4010
        // Load the new content type copy.
4011
        $copiedContentType = $contentTypeService->loadContentType($contentTypeId);
4012
        /* END: Use Case */
4013
4014
        $this->assertEquals($contentTypeId, $copiedContentType->id);
4015
    }
4016
4017
    /**
4018
     * Test for the deleteContentType() method.
4019
     *
4020
     * @see \eZ\Publish\API\Repository\ContentTypeService::deleteContentType()
4021
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCopyContentType
4022
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifierThrowsNotFoundException
4023
     */
4024
    public function testDeleteContentTypeInTransactionWithRollback()
4025
    {
4026
        $repository = $this->getRepository();
4027
4028
        /* BEGIN: Use Case */
4029
        $contentTypeService = $repository->getContentTypeService();
4030
4031
        // Load content type to copy
4032
        $contentType = $contentTypeService->loadContentTypeByIdentifier('comment');
4033
4034
        // Start a new transaction
4035
        $repository->beginTransaction();
4036
4037
        try {
4038
            // Delete the "comment" content type.
4039
            $contentTypeService->deleteContentType($contentType);
4040
        } catch (Exception $e) {
4041
            // Cleanup hanging transaction on error
4042
            $repository->rollback();
4043
            throw $e;
4044
        }
4045
4046
        // Rollback all changes
4047
        $repository->rollback();
4048
4049
        // Load currently deleted and rollbacked content type
4050
        $commentType = $contentTypeService->loadContentTypeByIdentifier('comment');
4051
        /* END: Use Case */
4052
4053
        $this->assertEquals('comment', $commentType->identifier);
4054
    }
4055
4056
    /**
4057
     * Test for the deleteContentType() method.
4058
     *
4059
     * @see \eZ\Publish\API\Repository\ContentTypeService::deleteContentType()
4060
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testCopyContentType
4061
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifierThrowsNotFoundException
4062
     */
4063 View Code Duplication
    public function testDeleteContentTypeInTransactionWithCommit()
4064
    {
4065
        $repository = $this->getRepository();
4066
4067
        /* BEGIN: Use Case */
4068
        $contentTypeService = $repository->getContentTypeService();
4069
4070
        // Load content type to copy
4071
        $contentType = $contentTypeService->loadContentTypeByIdentifier('comment');
4072
4073
        // Start a new transaction
4074
        $repository->beginTransaction();
4075
4076
        try {
4077
            // Delete the "comment" content type.
4078
            $contentTypeService->deleteContentType($contentType);
4079
4080
            // Commit all changes
4081
            $repository->commit();
4082
        } catch (Exception $e) {
4083
            // Cleanup hanging transaction on error
4084
            $repository->rollback();
4085
            throw $e;
4086
        }
4087
4088
        try {
4089
            // This call will fail with a "NotFoundException"
4090
            $contentTypeService->loadContentTypeByIdentifier('comment');
4091
        } catch (NotFoundException $e) {
4092
            // Expected execution path
4093
        }
4094
        /* END: Use Case */
4095
4096
        $this->assertTrue(isset($e), 'Can still load content type after rollback.');
4097
    }
4098
4099
    /**
4100
     * Test for the assignContentTypeGroup() method.
4101
     *
4102
     * @see \eZ\Publish\API\Repository\ContentTypeService::assignContentTypeGroup()
4103
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAssignContentTypeGroup
4104
     */
4105 View Code Duplication
    public function testAssignContentTypeGroupInTransactionWithRollback()
4106
    {
4107
        $repository = $this->getRepository();
4108
4109
        /* BEGIN: Use Case */
4110
        $contentTypeService = $repository->getContentTypeService();
4111
4112
        $mediaGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Media');
4113
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
4114
4115
        // Start a new transaction
4116
        $repository->beginTransaction();
4117
4118
        try {
4119
            // Assign group to content type
4120
            $contentTypeService->assignContentTypeGroup($folderType, $mediaGroup);
4121
        } catch (Exception $e) {
4122
            // Cleanup hanging transaction on error
4123
            $repository->rollback();
4124
            throw $e;
4125
        }
4126
4127
        // Rollback all changes
4128
        $repository->rollback();
4129
4130
        // Load all content types assigned to media group
4131
        $contentTypes = $contentTypeService->loadContentTypes($mediaGroup);
4132
4133
        $contentTypeIds = [];
4134
        foreach ($contentTypes as $contentType) {
4135
            $contentTypeIds[] = $contentType->id;
4136
        }
4137
        /* END: Use Case */
4138
4139
        $this->assertFalse(
4140
            in_array($folderType->id, $contentTypeIds),
4141
            'Folder content type is still in media group after rollback.'
4142
        );
4143
    }
4144
4145
    /**
4146
     * Test for the assignContentTypeGroup() method.
4147
     *
4148
     * @see \eZ\Publish\API\Repository\ContentTypeService::assignContentTypeGroup()
4149
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testAssignContentTypeGroup
4150
     */
4151 View Code Duplication
    public function testAssignContentTypeGroupInTransactionWithCommit()
4152
    {
4153
        $repository = $this->getRepository();
4154
4155
        /* BEGIN: Use Case */
4156
        $contentTypeService = $repository->getContentTypeService();
4157
4158
        $mediaGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Media');
4159
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
4160
4161
        // Start a new transaction
4162
        $repository->beginTransaction();
4163
4164
        try {
4165
            // Assign group to content type
4166
            $contentTypeService->assignContentTypeGroup($folderType, $mediaGroup);
4167
4168
            // Commit all changes
4169
            $repository->commit();
4170
        } catch (Exception $e) {
4171
            // Cleanup hanging transaction on error
4172
            $repository->rollback();
4173
            throw $e;
4174
        }
4175
4176
        // Load all content types assigned to media group
4177
        $contentTypes = $contentTypeService->loadContentTypes($mediaGroup);
4178
4179
        $contentTypeIds = [];
4180
        foreach ($contentTypes as $contentType) {
4181
            $contentTypeIds[] = $contentType->id;
4182
        }
4183
        /* END: Use Case */
4184
4185
        $this->assertTrue(
4186
            in_array($folderType->id, $contentTypeIds),
4187
            'Folder content type not in media group after commit.'
4188
        );
4189
    }
4190
4191
    /**
4192
     * Test for the isContentTypeUsed() method.
4193
     *
4194
     * @see \eZ\Publish\API\Repository\ContentTypeService::isContentTypeUsed()
4195
     */
4196
    public function testIsContentTypeUsed()
4197
    {
4198
        $repository = $this->getRepository();
4199
4200
        /* BEGIN: Use Case */
4201
        $contentTypeService = $repository->getContentTypeService();
4202
4203
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
4204
        $eventType = $contentTypeService->loadContentTypeByIdentifier('event');
4205
4206
        $isFolderUsed = $contentTypeService->isContentTypeUsed($folderType);
4207
        $isEventUsed = $contentTypeService->isContentTypeUsed($eventType);
4208
        /* END: Use Case */
4209
4210
        $this->assertTrue($isFolderUsed);
4211
        $this->assertFalse($isEventUsed);
4212
    }
4213
4214
    /**
4215
     * @covers \eZ\Publish\API\Repository\ContentTypeService::removeContentTypeTranslation
4216
     *
4217
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
4218
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
4219
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
4220
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
4221
     */
4222
    public function testRemoveContentTypeTranslation()
4223
    {
4224
        $repository = $this->getRepository();
4225
        $contentTypeService = $repository->getContentTypeService();
4226
4227
        $contentTypeDraft = $this->createContentTypeDraft();
4228
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
4229
4230
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
4231
4232
        $this->assertEquals(
4233
            [
4234
                'eng-US' => 'Blog post',
4235
                'ger-DE' => 'Blog-Eintrag',
4236
            ],
4237
            $contentType->getNames()
4238
        );
4239
4240
        $contentTypeService->removeContentTypeTranslation(
4241
            $contentTypeService->createContentTypeDraft($contentType),
4242
            'ger-DE'
4243
        );
4244
4245
        $loadedContentTypeDraft = $contentTypeService->loadContentTypeDraft($contentType->id);
4246
4247
        $this->assertArrayNotHasKey('ger-DE', $loadedContentTypeDraft->getNames());
4248
        $this->assertArrayNotHasKey('ger-DE', $loadedContentTypeDraft->getDescriptions());
4249
4250
        foreach ($loadedContentTypeDraft->fieldDefinitions as $fieldDefinition) {
4251
            $this->assertArrayNotHasKey('ger-DE', $fieldDefinition->getNames());
4252
            $this->assertArrayNotHasKey('ger-DE', $fieldDefinition->getDescriptions());
4253
        }
4254
    }
4255
4256
    /**
4257
     * @covers \eZ\Publish\API\Repository\ContentTypeService::removeContentTypeTranslation
4258
     *
4259
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
4260
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
4261
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
4262
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
4263
     */
4264
    public function testRemoveContentTypeTranslationWithMultilingualData()
4265
    {
4266
        $repository = $this->getRepository();
4267
        $contentTypeService = $repository->getContentTypeService();
4268
4269
        $selectionFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('selection', 'ezselection');
4270
4271
        $selectionFieldCreate->names = [
4272
            'eng-US' => 'Selection',
4273
            'ger-DE' => 'GER Selection',
4274
        ];
4275
4276
        $selectionFieldCreate->fieldGroup = 'blog-content';
4277
        $selectionFieldCreate->position = 3;
4278
        $selectionFieldCreate->isTranslatable = true;
4279
        $selectionFieldCreate->isRequired = true;
4280
        $selectionFieldCreate->isInfoCollector = false;
4281
        $selectionFieldCreate->validatorConfiguration = [];
4282
        $selectionFieldCreate->fieldSettings = [
4283
            'multilingualOptions' => [
4284
                'eng-US' => [
4285
                    0 => 'A first',
4286
                    1 => 'Bielefeld',
4287
                    2 => 'Sindelfingen',
4288
                    3 => 'Turtles',
4289
                    4 => 'Zombies',
4290
                ],
4291
                'ger-DE' => [
4292
                    0 => 'Berlin',
4293
                    1 => 'Cologne',
4294
                    2 => 'Bonn',
4295
                    3 => 'Frankfurt',
4296
                    4 => 'Hamburg',
4297
                ],
4298
            ],
4299
        ];
4300
        $selectionFieldCreate->isSearchable = false;
4301
4302
        $contentTypeDraft = $this->createContentTypeDraft([$selectionFieldCreate]);
4303
4304
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
4305
4306
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
4307
4308
        $contentTypeService->removeContentTypeTranslation(
4309
            $contentTypeService->createContentTypeDraft($contentType),
4310
            'ger-DE'
4311
        );
4312
4313
        $loadedContentTypeDraft = $contentTypeService->loadContentTypeDraft($contentType->id);
4314
4315
        $fieldDefinition = $loadedContentTypeDraft->getFieldDefinition('selection');
4316
        $this->assertArrayNotHasKey('ger-DE', $fieldDefinition->fieldSettings['multilingualOptions']);
4317
    }
4318
4319
    /**
4320
     * @covers \eZ\Publish\API\Repository\ContentTypeService::updateContentTypeDraft
4321
     *
4322
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
4323
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
4324
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
4325
     */
4326
    public function testUpdateContentTypeDraftWithNewTranslationWithMultilingualData()
4327
    {
4328
        $repository = $this->getRepository();
4329
        $contentTypeService = $repository->getContentTypeService();
4330
4331
        $selectionFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('selection', 'ezselection');
4332
4333
        $selectionFieldCreate->names = [
4334
            'eng-US' => 'Selection',
4335
            'ger-DE' => 'GER Selection',
4336
        ];
4337
4338
        $selectionFieldCreate->fieldGroup = 'blog-content';
4339
        $selectionFieldCreate->position = 3;
4340
        $selectionFieldCreate->isTranslatable = true;
4341
        $selectionFieldCreate->isRequired = true;
4342
        $selectionFieldCreate->isInfoCollector = false;
4343
        $selectionFieldCreate->validatorConfiguration = [];
4344
        $selectionFieldCreate->fieldSettings = [
4345
            'multilingualOptions' => [
4346
                'eng-US' => [
4347
                    0 => 'A first',
4348
                    1 => 'Bielefeld',
4349
                    2 => 'Sindelfingen',
4350
                    3 => 'Turtles',
4351
                    4 => 'Zombies',
4352
                ],
4353
                'ger-DE' => [
4354
                    0 => 'Berlin',
4355
                    1 => 'Cologne',
4356
                    2 => 'Bonn',
4357
                    3 => 'Frankfurt',
4358
                    4 => 'Hamburg',
4359
                ],
4360
            ],
4361
        ];
4362
        $selectionFieldCreate->isSearchable = false;
4363
4364
        $contentTypeDraft = $this->createContentTypeDraft([$selectionFieldCreate]);
4365
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
4366
4367
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
4368
        // sanity check
4369
        self::assertEquals(
4370
            ['eng-US', 'ger-DE'],
4371
            array_keys($contentType->getNames())
4372
        );
4373
4374
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
4375
        $updateStruct = $contentTypeService->newContentTypeUpdateStruct();
4376
        $updateStruct->names = [
4377
            'eng-GB' => 'BrE blog post',
4378
        ];
4379
4380
        $selectionFieldUpdate = $contentTypeService->newFieldDefinitionUpdateStruct();
4381
4382
        $selectionFieldUpdate->names = [
4383
            'eng-GB' => 'GB Selection',
4384
        ];
4385
4386
        $selectionFieldUpdate->fieldGroup = 'blog-content';
4387
        $selectionFieldUpdate->position = 3;
4388
        $selectionFieldUpdate->isTranslatable = true;
4389
        $selectionFieldUpdate->isRequired = true;
4390
        $selectionFieldUpdate->isInfoCollector = false;
4391
        $selectionFieldUpdate->validatorConfiguration = [];
4392
        $selectionFieldUpdate->fieldSettings = [
4393
            'multilingualOptions' => [
4394
                'eng-US' => [
4395
                    0 => 'A first',
4396
                    1 => 'Bielefeld',
4397
                    2 => 'Sindelfingen',
4398
                    3 => 'Turtles',
4399
                    4 => 'Zombies',
4400
                ],
4401
                'ger-DE' => [
4402
                    0 => 'Berlin',
4403
                    1 => 'Cologne',
4404
                    2 => 'Bonn',
4405
                    3 => 'Frankfurt',
4406
                    4 => 'Hamburg',
4407
                ],
4408
                'eng-GB' => [
4409
                    0 => 'London',
4410
                    1 => 'Liverpool',
4411
                ],
4412
            ],
4413
        ];
4414
        $selectionFieldUpdate->isSearchable = false;
4415
4416
        $contentTypeService->updateFieldDefinition(
4417
            $contentTypeDraft,
4418
            $contentType->getFieldDefinition('selection'),
0 ignored issues
show
Bug introduced by
It seems like $contentType->getFieldDefinition('selection') can be null; however, updateFieldDefinition() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
4419
            $selectionFieldUpdate
4420
        );
4421
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $updateStruct);
4422
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
4423
4424
        $loadedFieldDefinition = $contentTypeService->loadContentType($contentType->id)->getFieldDefinition('selection');
4425
        self::assertEquals(
4426
            [
4427
                'eng-US' => [
4428
                    0 => 'A first',
4429
                    1 => 'Bielefeld',
4430
                    2 => 'Sindelfingen',
4431
                    3 => 'Turtles',
4432
                    4 => 'Zombies',
4433
                ],
4434
                'ger-DE' => [
4435
                    0 => 'Berlin',
4436
                    1 => 'Cologne',
4437
                    2 => 'Bonn',
4438
                    3 => 'Frankfurt',
4439
                    4 => 'Hamburg',
4440
                ],
4441
                'eng-GB' => [
4442
                    0 => 'London',
4443
                    1 => 'Liverpool',
4444
                ],
4445
            ],
4446
            $loadedFieldDefinition->fieldSettings['multilingualOptions']
4447
        );
4448
    }
4449
4450
    /**
4451
     * Test for the deleteUserDrafts() method.
4452
     *
4453
     * @see \eZ\Publish\API\Repository\ContentTypeService::deleteUserDrafts()
4454
     */
4455 View Code Duplication
    public function testDeleteUserDrafts()
4456
    {
4457
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
4458
4459
        $repository = $this->getRepository();
4460
        $userService = $repository->getUserService();
0 ignored issues
show
Unused Code introduced by
$userService 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...
4461
        $permissionResolver = $repository->getPermissionResolver();
4462
        $contentTypeService = $repository->getContentTypeService();
4463
4464
        $draft = $this->createContentTypeDraft();
4465
        $user = $permissionResolver->getCurrentUserReference();
4466
4467
        $contentTypeService->deleteUserDrafts($user->getUserId());
4468
        $contentTypeDraft = $contentTypeService->loadContentTypeDraft($draft->id);
0 ignored issues
show
Unused Code introduced by
$contentTypeDraft 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...
4469
    }
4470
}
4471