EntityTypeTest.php 17.7 KB
Newer Older
1
2
3
4
5
<?php

namespace Drupal\Tests\Core\Entity;

use Drupal\Core\Entity\EntityType;
6
use Drupal\Core\Entity\EntityTypeInterface;
7
use Drupal\Core\StringTranslation\TranslatableMarkup;
8
use Drupal\Core\StringTranslation\TranslationInterface;
9
10
11
use Drupal\Tests\UnitTestCase;

/**
12
 * @coversDefaultClass \Drupal\Core\Entity\EntityType
13
14
15
16
17
18
19
20
21
22
23
24
25
 * @group Entity
 */
class EntityTypeTest extends UnitTestCase {

  /**
   * Sets up an EntityType object for a given set of values.
   *
   * @param array $definition
   *   An array of values to use for the EntityType.
   *
   * @return \Drupal\Core\Entity\EntityTypeInterface
   */
  protected function setUpEntityType($definition) {
26
    $definition += [
27
      'id' => 'example_entity_type',
28
    ];
29
30
31
    return new EntityType($definition);
  }

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  /**
   * @covers ::get
   *
   * @dataProvider providerTestGet
   */
  public function testGet(array $defintion, $key, $expected) {
    $entity_type = $this->setUpEntityType($defintion);
    $this->assertSame($expected, $entity_type->get($key));
  }

  /**
   * @covers ::set
   * @covers ::get
   *
   * @dataProvider providerTestSet
   */
  public function testSet($key, $value) {
    $entity_type = $this->setUpEntityType([]);
    $this->assertInstanceOf('Drupal\Core\Entity\EntityTypeInterface', $entity_type->set($key, $value));
    $this->assertSame($value, $entity_type->get($key));
    $this->assertNoPublicProperties($entity_type);
  }

55
56
57
58
59
60
  /**
   * Tests the getKeys() method.
   *
   * @dataProvider providerTestGetKeys
   */
  public function testGetKeys($entity_keys, $expected) {
61
    $entity_type = $this->setUpEntityType(['entity_keys' => $entity_keys]);
62
63
64
65
66
    $expected += [
      'default_langcode' => 'default_langcode',
      'revision_translation_affected' => 'revision_translation_affected',
    ];
    $this->assertSame($expected, $entity_type->getKeys());
67
68
69
70
71
72
73
74
  }

  /**
   * Tests the getKey() method.
   *
   * @dataProvider providerTestGetKeys
   */
  public function testGetKey($entity_keys, $expected) {
75
    $entity_type = $this->setUpEntityType(['entity_keys' => $entity_keys]);
76
77
78
79
80
81
82
83
84
85
    $this->assertSame($expected['bundle'], $entity_type->getKey('bundle'));
    $this->assertSame(FALSE, $entity_type->getKey('bananas'));
  }

  /**
   * Tests the hasKey() method.
   *
   * @dataProvider providerTestGetKeys
   */
  public function testHasKey($entity_keys, $expected) {
86
    $entity_type = $this->setUpEntityType(['entity_keys' => $entity_keys]);
87
88
89
90
91
    $this->assertSame(!empty($expected['bundle']), $entity_type->hasKey('bundle'));
    $this->assertSame(!empty($expected['id']), $entity_type->hasKey('id'));
    $this->assertSame(FALSE, $entity_type->hasKey('bananas'));
  }

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  /**
   * Provides test data for testGet.
   */
  public function providerTestGet() {
    return [
      [[], 'provider', NULL],
      [['provider' => ''], 'provider', ''],
      [['provider' => 'test'], 'provider', 'test'],
      [[], 'something_additional', NULL],
      [['something_additional' => ''], 'something_additional', ''],
      [['something_additional' => 'additional'], 'something_additional', 'additional'],
    ];
  }

  /**
   * Provides test data for testSet.
   */
  public function providerTestSet() {
    return [
      ['provider', NULL],
      ['provider', ''],
      ['provider', 'test'],
      ['something_additional', NULL],
      ['something_additional', ''],
      ['something_additional', 'additional'],
    ];
  }

120
121
122
123
  /**
   * Provides test data.
   */
  public function providerTestGetKeys() {
124
125
126
127
128
    return [
      [[], ['revision' => '', 'bundle' => '', 'langcode' => '']],
      [['id' => 'id'], ['id' => 'id', 'revision' => '', 'bundle' => '', 'langcode' => '']],
      [['bundle' => 'bundle'], ['bundle' => 'bundle', 'revision' => '', 'langcode' => '']],
    ];
129
130
  }

131
132
133
134
135
136
137
138
139
140
141
142
  /**
   * Tests the isInternal() method.
   */
  public function testIsInternal() {
    $entity_type = $this->setUpEntityType(['internal' => TRUE]);
    $this->assertTrue($entity_type->isInternal());
    $entity_type = $this->setUpEntityType(['internal' => FALSE]);
    $this->assertFalse($entity_type->isInternal());
    $entity_type = $this->setUpEntityType([]);
    $this->assertFalse($entity_type->isInternal());
  }

143
144
145
146
  /**
   * Tests the isRevisionable() method.
   */
  public function testIsRevisionable() {
147
    $entity_type = $this->setUpEntityType(['entity_keys' => ['id' => 'id']]);
148
    $this->assertFalse($entity_type->isRevisionable());
149
    $entity_type = $this->setUpEntityType(['entity_keys' => ['id' => 'id', 'revision' => FALSE]]);
150
    $this->assertFalse($entity_type->isRevisionable());
151
    $entity_type = $this->setUpEntityType(['entity_keys' => ['id' => 'id', 'revision' => TRUE]]);
152
153
154
    $this->assertTrue($entity_type->isRevisionable());
  }

155
  /**
156
   * Tests the getHandler() method.
157
   */
158
159
  public function testGetHandler() {
    $controller = $this->getTestHandlerClass();
160
161
    $entity_type = $this->setUpEntityType([
      'handlers' => [
162
        'storage' => $controller,
163
        'form' => [
164
          'default' => $controller,
165
166
167
        ],
      ],
    ]);
168
169
    $this->assertSame($controller, $entity_type->getHandlerClass('storage'));
    $this->assertSame($controller, $entity_type->getHandlerClass('form', 'default'));
170
171
    $this->assertNull($entity_type->getHandlerClass('foo'));
    $this->assertNull($entity_type->getHandlerClass('foo', 'bar'));
172
173
174
175
176
177
  }

  /**
   * Tests the getStorageClass() method.
   */
  public function testGetStorageClass() {
178
    $controller = $this->getTestHandlerClass();
179
180
    $entity_type = $this->setUpEntityType([
      'handlers' => [
181
        'storage' => $controller,
182
183
      ],
    ]);
184
185
186
    $this->assertSame($controller, $entity_type->getStorageClass());
  }

187
188
189
190
191
  /**
   * Tests the setStorageClass() method.
   */
  public function testSetStorageClass() {
    $controller = $this->getTestHandlerClass();
192
    $entity_type = $this->setUpEntityType([]);
193
194
195
    $this->assertSame($entity_type, $entity_type->setStorageClass($controller));
  }

196
  /**
197
   * Tests the getListBuilderClass() method.
198
   */
199
  public function testGetListBuilderClass() {
200
    $controller = $this->getTestHandlerClass();
201
202
    $entity_type = $this->setUpEntityType([
      'handlers' => [
203
        'list_builder' => $controller,
204
205
      ],
    ]);
206
    $this->assertSame($controller, $entity_type->getListBuilderClass());
207
208
209
  }

  /**
210
   * Tests the getAccessControlClass() method.
211
   */
212
  public function testGetAccessControlClass() {
213
    $controller = $this->getTestHandlerClass();
214
215
    $entity_type = $this->setUpEntityType([
      'handlers' => [
216
        'access' => $controller,
217
218
      ],
    ]);
219
    $this->assertSame($controller, $entity_type->getAccessControlClass());
220
221
222
223
224
225
  }

  /**
   * Tests the getFormClass() method.
   */
  public function testGetFormClass() {
226
    $controller = $this->getTestHandlerClass();
227
    $operation = 'default';
228
229
230
    $entity_type = $this->setUpEntityType([
      'handlers' => [
        'form' => [
231
          $operation => $controller,
232
233
234
        ],
      ],
    ]);
235
236
237
238
239
240
241
    $this->assertSame($controller, $entity_type->getFormClass($operation));
  }

  /**
   * Tests the hasFormClasses() method.
   */
  public function testHasFormClasses() {
242
    $controller = $this->getTestHandlerClass();
243
    $operation = 'default';
244
245
246
    $entity_type1 = $this->setUpEntityType([
      'handlers' => [
        'form' => [
247
          $operation => $controller,
248
249
250
251
252
253
        ],
      ],
    ]);
    $entity_type2 = $this->setUpEntityType([
      'handlers' => [],
    ]);
254
255
256
257
258
259
260
261
    $this->assertTrue($entity_type1->hasFormClasses());
    $this->assertFalse($entity_type2->hasFormClasses());
  }

  /**
   * Tests the getViewBuilderClass() method.
   */
  public function testGetViewBuilderClass() {
262
    $controller = $this->getTestHandlerClass();
263
264
    $entity_type = $this->setUpEntityType([
      'handlers' => [
265
        'view_builder' => $controller,
266
267
      ],
    ]);
268
269
270
    $this->assertSame($controller, $entity_type->getViewBuilderClass());
  }

271
272
273
274
  /**
   * @covers ::__construct
   */
  public function testIdExceedsMaxLength() {
275
    $id = $this->randomMachineName(33);
276
    $message = 'Attempt to create an entity type with an ID longer than 32 characters: ' . $id;
277
278
    $this->expectException('Drupal\Core\Entity\Exception\EntityTypeIdLengthException');
    $this->expectExceptionMessage($message);
279
    $this->setUpEntityType(['id' => $id]);
280
281
  }

282
283
284
285
286
  /**
   * @covers ::getOriginalClass
   */
  public function testgetOriginalClassUnchanged() {
    $class = $this->randomMachineName();
287
    $entity_type = $this->setUpEntityType(['class' => $class]);
288
289
290
291
292
293
294
295
296
    $this->assertEquals($class, $entity_type->getOriginalClass());
  }

  /**
   * @covers ::setClass
   * @covers ::getOriginalClass
   */
  public function testgetOriginalClassChanged() {
    $class = $this->randomMachineName();
297
    $entity_type = $this->setUpEntityType(['class' => $class]);
298
299
300
301
    $entity_type->setClass($this->randomMachineName());
    $this->assertEquals($class, $entity_type->getOriginalClass());
  }

302
303
304
305
  /**
   * @covers ::id
   */
  public function testId() {
306
    $id = $this->randomMachineName(32);
307
    $entity_type = $this->setUpEntityType(['id' => $id]);
308
309
310
    $this->assertEquals($id, $entity_type->id());
  }

311
312
313
314
  /**
   * @covers ::getLabel
   */
  public function testGetLabel() {
315
    $translatable_label = new TranslatableMarkup($this->randomMachineName());
316
    $entity_type = $this->setUpEntityType(['label' => $translatable_label]);
317
318
319
    $this->assertSame($translatable_label, $entity_type->getLabel());

    $label = $this->randomMachineName();
320
    $entity_type = $this->setUpEntityType(['label' => $label]);
321
322
323
324
325
326
327
    $this->assertSame($label, $entity_type->getLabel());
  }

  /**
   * @covers ::getGroupLabel
   */
  public function testGetGroupLabel() {
328
    $translatable_group_label = new TranslatableMarkup($this->randomMachineName());
329
    $entity_type = $this->setUpEntityType(['group_label' => $translatable_group_label]);
330
331
332
    $this->assertSame($translatable_group_label, $entity_type->getGroupLabel());

    $default_label = $this->randomMachineName();
333
    $entity_type = $this->setUpEntityType(['group_label' => $default_label]);
334
335
    $this->assertSame($default_label, $entity_type->getGroupLabel());

336
337
    $default_label = new TranslatableMarkup('Other', [], ['context' => 'Entity type group']);
    $entity_type = $this->setUpEntityType(['group_label' => $default_label]);
338
339
340
    $this->assertSame($default_label, $entity_type->getGroupLabel());
  }

341
342
343
344
345
346
347
348
349
350
  /**
   * @covers ::getCollectionLabel
   */
  public function testGetCollectionLabel() {
    $translatable_label = new TranslatableMarkup('Entity test collection', [], [], $this->getStringTranslationStub());
    $entity_type = $this->setUpEntityType(['label_collection' => $translatable_label]);
    $entity_type->setStringTranslation($this->getStringTranslationStub());
    $this->assertEquals('Entity test collection', $entity_type->getCollectionLabel());
  }

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
  /**
   * @covers ::getSingularLabel
   */
  public function testGetSingularLabel() {
    $translatable_label = new TranslatableMarkup('entity test singular', [], [], $this->getStringTranslationStub());
    $entity_type = $this->setUpEntityType(['label_singular' => $translatable_label]);
    $entity_type->setStringTranslation($this->getStringTranslationStub());
    $this->assertEquals('entity test singular', $entity_type->getSingularLabel());
  }

  /**
   * @covers ::getSingularLabel
   */
  public function testGetSingularLabelDefault() {
    $entity_type = $this->setUpEntityType(['label' => 'Entity test Singular']);
    $entity_type->setStringTranslation($this->getStringTranslationStub());
    $this->assertEquals('entity test singular', $entity_type->getSingularLabel());
  }

  /**
   * @covers ::getPluralLabel
   */
  public function testGetPluralLabel() {
    $translatable_label = new TranslatableMarkup('entity test plural', [], [], $this->getStringTranslationStub());
    $entity_type = $this->setUpEntityType(['label_plural' => $translatable_label]);
    $entity_type->setStringTranslation($this->getStringTranslationStub());
    $this->assertEquals('entity test plural', $entity_type->getPluralLabel());
  }

  /**
   * @covers ::getPluralLabel
   */
  public function testGetPluralLabelDefault() {
    $entity_type = $this->setUpEntityType(['label' => 'Entity test Plural']);
    $entity_type->setStringTranslation($this->getStringTranslationStub());
    $this->assertEquals('entity test plural entities', $entity_type->getPluralLabel());
  }

  /**
   * @covers ::getCountLabel
   */
  public function testGetCountLabel() {
    $entity_type = $this->setUpEntityType(['label_count' => ['singular' => 'one entity test', 'plural' => '@count entity test']]);
    $entity_type->setStringTranslation($this->getStringTranslationStub());
    $this->assertEquals('one entity test', $entity_type->getCountLabel(1));
    $this->assertEquals('2 entity test', $entity_type->getCountLabel(2));
    $this->assertEquals('200 entity test', $entity_type->getCountLabel(200));
  }

  /**
   * @covers ::getCountLabel
   */
  public function testGetCountLabelDefault() {
    $entity_type = $this->setUpEntityType(['label' => 'Entity test Plural']);
    $entity_type->setStringTranslation($this->getStringTranslationStub());
    $this->assertEquals('1 entity test plural', $entity_type->getCountLabel(1));
    $this->assertEquals('2 entity test plural entities', $entity_type->getCountLabel(2));
    $this->assertEquals('200 entity test plural entities', $entity_type->getCountLabel(200));
  }

411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
  /**
   * Tests the ::getBundleLabel() method.
   *
   * @covers ::getBundleLabel
   * @dataProvider providerTestGetBundleLabel
   */
  public function testGetBundleLabel($definition, $expected) {
    $entity_type = $this->setUpEntityType($definition);
    $entity_type->setStringTranslation($this->getStringTranslationStub());
    $this->assertEquals($expected, $entity_type->getBundleLabel());
  }

  /**
   * Provides test data for ::testGetBundleLabel().
   */
  public function providerTestGetBundleLabel() {
    return [
      [['label' => 'Entity Label Foo'], 'Entity Label Foo bundle'],
      [['bundle_label' => 'Bundle Label Bar'], 'Bundle Label Bar'],
    ];
  }

433
434
435
436
437
438
  /**
   * Gets a mock controller class name.
   *
   * @return string
   *   A mock controller class name.
   */
439
440
  protected function getTestHandlerClass() {
    return get_class($this->getMockForAbstractClass('Drupal\Core\Entity\EntityHandlerBase'));
441
442
  }

443
444
445
446
447
  /**
   * @covers ::setLinkTemplate
   */
  public function testSetLinkTemplateWithInvalidPath() {
    $entity_type = $this->setUpEntityType(['id' => $this->randomMachineName()]);
448
    $this->expectException(\InvalidArgumentException::class);
449
450
451
    $entity_type->setLinkTemplate('test', 'invalid-path');
  }

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
  /**
   * Tests the constraint methods.
   *
   * @covers ::getConstraints
   * @covers ::setConstraints
   * @covers ::addConstraint
   */
  public function testConstraintMethods() {
    $definition = [
      'constraints' => [
        'EntityChanged' => [],
      ],
    ];
    $entity_type = $this->setUpEntityType($definition);
    $this->assertEquals($definition['constraints'], $entity_type->getConstraints());
    $entity_type->addConstraint('Test');
    $this->assertEquals($definition['constraints'] + ['Test' => NULL], $entity_type->getConstraints());
    $entity_type->setConstraints([]);
    $this->assertEquals([], $entity_type->getConstraints());
  }

473
474
475
476
477
478
479
480
481
482
  /**
   * Asserts there on no public properties on the object instance.
   *
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   */
  protected function assertNoPublicProperties(EntityTypeInterface $entity_type) {
    $reflection = new \ReflectionObject($entity_type);
    $this->assertEmpty($reflection->getProperties(\ReflectionProperty::IS_PUBLIC));
  }

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
  /**
   * Tests that the EntityType object can be serialized.
   */
  public function testIsSerializable() {
    $entity_type = $this->setUpEntityType([]);

    $translation = $this->prophesize(TranslationInterface::class);
    $translation->willImplement(\Serializable::class);
    $translation->serialize()->willThrow(\Exception::class);
    $translation_service = $translation->reveal();
    $translation_service->_serviceId = 'string_translation';

    $entity_type->setStringTranslation($translation_service);
    $entity_type = unserialize(serialize($entity_type));

    $this->assertEquals('example_entity_type', $entity_type->id());
  }

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
  /**
   * @covers ::getLabelCallback
   *
   * @group legacy
   *
   * @deprecatedMessage EntityType::getLabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794
   */
  public function testGetLabelCallack() {
    $entity_type = $this->setUpEntityType(['label_callback' => 'label_function']);
    $this->assertSame('label_function', $entity_type->getLabelCallback());

    $entity_type = $this->setUpEntityType([]);
    $this->assertNull($entity_type->getLabelCallback());
  }

  /**
   * @covers ::setLabelCallback
   *
   * @group legacy
   *
   * @deprecatedMessage EntityType::setLabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794
   */
  public function testSetLabelCallack() {
    $entity_type = $this->setUpEntityType([]);
    $entity_type->setLabelCallback('label_function');
    $this->assertSame('label_function', $entity_type->get('label_callback'));
  }

  /**
   * @covers ::hasLabelCallback
   *
   * @group legacy
   *
   * @deprecatedMessage EntityType::hasLabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794
   */
  public function testHasLabelCallack() {
    $entity_type = $this->setUpEntityType(['label_callback' => 'label_function']);
    $this->assertTrue($entity_type->hasLabelCallback());

    $entity_type = $this->setUpEntityType([]);
    $this->assertFalse($entity_type->hasLabelCallback());
  }

544
}