SqlContentEntityStorageSchemaTest.php 47.1 KB
Newer Older
1 2
<?php

3
namespace Drupal\Tests\Core\Entity\Sql;
4 5

use Drupal\Core\Entity\ContentEntityType;
6
use Drupal\Core\Entity\ContentEntityTypeInterface;
7 8 9 10
use Drupal\Core\Entity\Sql\DefaultTableMapping;
use Drupal\Tests\UnitTestCase;

/**
11
 * @coversDefaultClass \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema
12 13
 * @group Entity
 */
14
class SqlContentEntityStorageSchemaTest extends UnitTestCase {
15

16 17 18 19 20 21 22
  /**
   * The mocked DB schema handler.
   *
   * @var \Drupal\Core\Database\Schema|\PHPUnit_Framework_MockObject_MockObject
   */
  protected $dbSchemaHandler;

23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
  /**
   * The mocked entity manager used in this test.
   *
   * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
   */
  protected $entityManager;

  /**
   * The mocked entity type used in this test.
   *
   * @var \Drupal\Core\Entity\ContentEntityTypeInterface
   */
  protected $entityType;

  /**
   * The mocked SQL storage used in this test.
   *
40
   * @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage|\PHPUnit_Framework_MockObject_MockObject
41 42 43 44 45 46 47 48 49 50 51
   */
  protected $storage;

  /**
   * The mocked field definitions used in this test.
   *
   * @var \Drupal\Core\Field\FieldStorageDefinitionInterface[]|\PHPUnit_Framework_MockObject_MockObject[]
   */
  protected $storageDefinitions;

  /**
52
   * The storage schema handler used in this test.
53
   *
54
   * @var \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema|\PHPUnit_Framework_MockObject_MockObject.
55
   */
56
  protected $storageSchema;
57 58 59 60

  /**
   * {@inheritdoc}
   */
61
  protected function setUp() {
62
    $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
63
    $this->storage = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorage')
64 65 66 67 68 69 70 71 72
      ->disableOriginalConstructor()
      ->getMock();

    $this->storage->expects($this->any())
      ->method('getBaseTable')
      ->will($this->returnValue('entity_test'));

    // Add an ID field. This also acts as a test for a simple, single-column
    // field.
73 74 75
    $this->setUpStorageDefinition('id', [
      'columns' => [
        'value' => [
76
          'type' => 'int',
77 78 79
        ],
      ],
    ]);
80 81 82 83 84
  }

  /**
   * Tests the schema for non-revisionable, non-translatable entities.
   *
85 86 87 88 89 90 91 92 93 94 95
   * @covers ::__construct
   * @covers ::getEntitySchemaTables
   * @covers ::initializeBaseTable
   * @covers ::addTableDefaults
   * @covers ::getEntityIndexName
   * @covers ::getFieldIndexes
   * @covers ::getFieldUniqueKeys
   * @covers ::getFieldForeignKeys
   * @covers ::getFieldSchemaData
   * @covers ::processBaseTable
   * @covers ::processIdentifierSchema
96
   */
97
  public function testGetSchemaBase() {
98
    $this->entityType = new ContentEntityType([
99
      'id' => 'entity_test',
100 101
      'entity_keys' => ['id' => 'id'],
    ]);
102 103

    // Add a field with a 'length' constraint.
104 105 106
    $this->setUpStorageDefinition('name', [
      'columns' => [
        'value' => [
107 108
          'type' => 'varchar',
          'length' => 255,
109 110 111
        ],
      ],
    ]);
112
    // Add a multi-column field.
113 114 115
    $this->setUpStorageDefinition('description', [
      'columns' => [
        'value' => [
116
          'type' => 'text',
117 118
        ],
        'format' => [
119
          'type' => 'varchar',
120 121 122
        ],
      ],
    ]);
123
    // Add a field with a unique key.
124 125 126
    $this->setUpStorageDefinition('uuid', [
      'columns' => [
        'value' => [
127 128
          'type' => 'varchar',
          'length' => 128,
129 130 131 132 133 134
        ],
      ],
      'unique keys' => [
        'value' => ['value'],
      ],
    ]);
135
    // Add a field with a unique key, specified as column name and length.
136 137 138
    $this->setUpStorageDefinition('hash', [
      'columns' => [
        'value' => [
139 140
          'type' => 'varchar',
          'length' => 20,
141 142 143 144 145 146
        ],
      ],
      'unique keys' => [
        'value' => [['value', 10]],
      ],
    ]);
147
    // Add a field with a multi-column unique key.
148 149 150
    $this->setUpStorageDefinition('email', [
      'columns' => [
        'username' => [
151
          'type' => 'varchar',
152 153
        ],
        'hostname' => [
154
          'type' => 'varchar',
155 156
        ],
        'domain' => [
157
          'type' => 'varchar',
158 159 160 161 162 163
        ]
      ],
      'unique keys' => [
        'email' => ['username', 'hostname', ['domain', 3]],
      ],
    ]);
164
    // Add a field with an index.
165 166 167
    $this->setUpStorageDefinition('owner', [
      'columns' => [
        'target_id' => [
168
          'type' => 'int',
169 170 171 172 173 174
        ],
      ],
      'indexes' => [
        'target_id' => ['target_id'],
      ],
    ]);
175
    // Add a field with an index, specified as column name and length.
176 177 178
    $this->setUpStorageDefinition('translator', [
      'columns' => [
        'target_id' => [
179
          'type' => 'int',
180 181 182 183 184 185
        ],
      ],
      'indexes' => [
        'target_id' => [['target_id', 10]],
      ],
    ]);
186
    // Add a field with a multi-column index.
187 188 189
    $this->setUpStorageDefinition('location', [
      'columns' => [
        'country' => [
190
          'type' => 'varchar',
191 192
        ],
        'state' => [
193
          'type' => 'varchar',
194 195
        ],
        'city' => [
196
          'type' => 'varchar',
197 198 199 200 201 202
        ]
      ],
      'indexes' => [
        'country_state_city' => ['country', 'state', ['city', 10]],
      ],
    ]);
203
    // Add a field with a foreign key.
204 205 206
    $this->setUpStorageDefinition('editor', [
      'columns' => [
        'target_id' => [
207
          'type' => 'int',
208 209 210 211
        ],
      ],
      'foreign keys' => [
        'user_id' => [
212
          'table' => 'users',
213 214 215 216
          'columns' => ['target_id' => 'uid'],
        ],
      ],
    ]);
217
    // Add a multi-column field with a foreign key.
218 219 220
    $this->setUpStorageDefinition('editor_revision', [
      'columns' => [
        'target_id' => [
221
          'type' => 'int',
222 223
        ],
        'target_revision_id' => [
224
          'type' => 'int',
225 226 227 228
        ],
      ],
      'foreign keys' => [
        'user_id' => [
229
          'table' => 'users',
230 231 232 233
          'columns' => ['target_id' => 'uid'],
        ],
      ],
    ]);
234
    // Add a field with a really long index.
235 236 237
    $this->setUpStorageDefinition('long_index_name', [
      'columns' => [
        'long_index_name' => [
238
          'type' => 'int',
239 240 241 242 243 244 245 246 247
        ],
      ],
      'indexes' => [
        'long_index_name_really_long_long_name' => [['long_index_name', 10]],
      ],
    ]);

    $expected = [
      'entity_test' => [
248
        'description' => 'The base table for entity_test entities.',
249 250
        'fields' => [
          'id' => [
251 252
            'type' => 'serial',
            'not null' => TRUE,
253 254
          ],
          'name' => [
255 256
            'type' => 'varchar',
            'length' => 255,
257
            'not null' => FALSE,
258 259
          ],
          'description__value' => [
260
            'type' => 'text',
261
            'not null' => FALSE,
262 263
          ],
          'description__format' => [
264
            'type' => 'varchar',
265
            'not null' => FALSE,
266 267
          ],
          'uuid' => [
268 269
            'type' => 'varchar',
            'length' => 128,
270
            'not null' => FALSE,
271 272
          ],
          'hash' => [
273 274
            'type' => 'varchar',
            'length' => 20,
275
            'not null' => FALSE,
276 277
          ],
          'email__username' => [
278
            'type' => 'varchar',
279
            'not null' => FALSE,
280 281
          ],
          'email__hostname' => [
282
            'type' => 'varchar',
283
            'not null' => FALSE,
284 285
          ],
          'email__domain' => [
286
            'type' => 'varchar',
287
            'not null' => FALSE,
288 289
          ],
          'owner' => [
290
            'type' => 'int',
291
            'not null' => FALSE,
292 293
          ],
          'translator' => [
294
            'type' => 'int',
295
            'not null' => FALSE,
296 297
          ],
          'location__country' => [
298
            'type' => 'varchar',
299
            'not null' => FALSE,
300 301
          ],
          'location__state' => [
302
            'type' => 'varchar',
303
            'not null' => FALSE,
304 305
          ],
          'location__city' => [
306
            'type' => 'varchar',
307
            'not null' => FALSE,
308 309
          ],
          'editor' => [
310
            'type' => 'int',
311
            'not null' => FALSE,
312 313
          ],
          'editor_revision__target_id' => [
314
            'type' => 'int',
315
            'not null' => FALSE,
316 317
          ],
          'editor_revision__target_revision_id' => [
318
            'type' => 'int',
319
            'not null' => FALSE,
320 321
          ],
          'long_index_name' => [
322
            'type' => 'int',
323
            'not null' => FALSE,
324 325 326 327 328 329 330
          ],
        ],
        'primary key' => ['id'],
        'unique keys' => [
          'entity_test_field__uuid__value' => ['uuid'],
          'entity_test_field__hash__value' => [['hash', 10]],
          'entity_test_field__email__email' => [
331 332
            'email__username',
            'email__hostname',
333 334 335 336 337 338 339 340 341
            ['email__domain', 3],
          ],
        ],
        'indexes' => [
          'entity_test_field__owner__target_id' => ['owner'],
          'entity_test_field__translator__target_id' => [
            ['translator', 10],
          ],
          'entity_test_field__location__country_state_city' => [
342 343
            'location__country',
            'location__state',
344 345 346 347 348 349 350 351 352
            ['location__city', 10],
          ],
          'entity_test__b588603cb9' => [
            ['long_index_name', 10],
          ],

        ],
        'foreign keys' => [
          'entity_test_field__editor__user_id' => [
353
            'table' => 'users',
354 355 356
            'columns' => ['editor' => 'uid'],
          ],
          'entity_test_field__editor_revision__user_id' => [
357
            'table' => 'users',
358 359 360 361 362
            'columns' => ['editor_revision__target_id' => 'uid'],
          ],
        ],
      ],
    ];
363

364
    $this->setUpStorageSchema($expected);
365

366
    $table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
367
    $table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions));
368
    $table_mapping->setExtraColumns('entity_test', ['default_langcode']);
369 370 371 372 373

    $this->storage->expects($this->any())
      ->method('getTableMapping')
      ->will($this->returnValue($table_mapping));

374 375 376
    $this->assertNull(
      $this->storageSchema->onEntityTypeCreate($this->entityType)
    );
377 378 379 380 381
  }

  /**
   * Tests the schema for revisionable, non-translatable entities.
   *
382 383 384 385 386 387 388 389
   * @covers ::__construct
   * @covers ::getEntitySchemaTables
   * @covers ::initializeBaseTable
   * @covers ::initializeRevisionTable
   * @covers ::addTableDefaults
   * @covers ::getEntityIndexName
   * @covers ::processRevisionTable
   * @covers ::processIdentifierSchema
390 391
   */
  public function testGetSchemaRevisionable() {
392
    $this->entityType = new ContentEntityType([
393
      'id' => 'entity_test',
394
      'entity_keys' => [
395 396
        'id' => 'id',
        'revision' => 'revision_id',
397 398
      ],
    ]);
399 400 401 402 403

    $this->storage->expects($this->exactly(2))
      ->method('getRevisionTable')
      ->will($this->returnValue('entity_test_revision'));

404 405 406
    $this->setUpStorageDefinition('revision_id', [
      'columns' => [
        'value' => [
407
          'type' => 'int',
408 409 410
        ],
      ],
    ]);
411

412 413
    $expected = [
      'entity_test' => [
414
        'description' => 'The base table for entity_test entities.',
415 416
        'fields' => [
          'id' => [
417 418
            'type' => 'serial',
            'not null' => TRUE,
419 420
          ],
          'revision_id' => [
421
            'type' => 'int',
422
            'not null' => FALSE,
423 424 425 426 427 428 429 430 431
          ]
        ],
        'primary key' => ['id'],
        'unique keys' => [
          'entity_test__revision_id' => ['revision_id'],
        ],
        'indexes' => [],
        'foreign keys' => [
          'entity_test__revision' => [
432
            'table' => 'entity_test_revision',
433 434 435 436 437
            'columns' => ['revision_id' => 'revision_id'],
          ]
        ],
      ],
      'entity_test_revision' => [
438
        'description' => 'The revision table for entity_test entities.',
439 440
        'fields' => [
          'id' => [
441 442
            'type' => 'int',
            'not null' => TRUE,
443 444
          ],
          'revision_id' => [
445
            'type' => 'serial',
446
            'not null' => TRUE,
447 448 449 450 451 452 453 454 455
          ],
        ],
        'primary key' => ['revision_id'],
        'unique keys' => [],
        'indexes' => [
          'entity_test__id' => ['id'],
        ],
        'foreign keys' => [
          'entity_test__revisioned' => [
456
            'table' => 'entity_test',
457 458 459 460 461
            'columns' => ['id' => 'id'],
          ],
        ],
      ],
    ];
462

463
    $this->setUpStorageSchema($expected);
464

465
    $table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
466 467 468 469 470 471
    $table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions));
    $table_mapping->setFieldNames('entity_test_revision', array_keys($this->storageDefinitions));

    $this->storage->expects($this->any())
      ->method('getTableMapping')
      ->will($this->returnValue($table_mapping));
472

473
    $this->storageSchema->onEntityTypeCreate($this->entityType);
474 475 476 477 478
  }

  /**
   * Tests the schema for non-revisionable, translatable entities.
   *
479 480 481 482 483 484
   * @covers ::__construct
   * @covers ::getEntitySchemaTables
   * @covers ::initializeDataTable
   * @covers ::addTableDefaults
   * @covers ::getEntityIndexName
   * @covers ::processDataTable
485 486
   */
  public function testGetSchemaTranslatable() {
487
    $this->entityType = new ContentEntityType([
488
      'id' => 'entity_test',
489
      'entity_keys' => [
490
        'id' => 'id',
491
        'langcode' => 'langcode',
492 493
      ],
    ]);
494

495
    $this->storage->expects($this->any())
496 497 498
      ->method('getDataTable')
      ->will($this->returnValue('entity_test_field_data'));

499 500 501
    $this->setUpStorageDefinition('langcode', [
      'columns' => [
        'value' => [
502
          'type' => 'varchar',
503 504 505
        ],
      ],
    ]);
506

507 508 509
    $this->setUpStorageDefinition('default_langcode', [
      'columns' => [
        'value' => [
510 511
          'type' => 'int',
          'size' => 'tiny',
512 513 514
        ],
      ],
    ]);
515

516 517
    $expected = [
      'entity_test' => [
518
        'description' => 'The base table for entity_test entities.',
519 520
        'fields' => [
          'id' => [
521 522
            'type' => 'serial',
            'not null' => TRUE,
523 524
          ],
          'langcode' => [
525 526
            'type' => 'varchar',
            'not null' => TRUE,
527 528 529 530 531 532 533 534
          ]
        ],
        'primary key' => ['id'],
        'unique keys' => [],
        'indexes' => [],
        'foreign keys' => [],
      ],
      'entity_test_field_data' => [
535
        'description' => 'The data table for entity_test entities.',
536 537
        'fields' => [
          'id' => [
538 539
            'type' => 'int',
            'not null' => TRUE,
540 541
          ],
          'langcode' => [
542 543
            'type' => 'varchar',
            'not null' => TRUE,
544 545
          ],
          'default_langcode' => [
546 547
            'type' => 'int',
            'size' => 'tiny',
548
            'not null' => TRUE,
549 550 551 552 553 554
          ],
        ],
        'primary key' => ['id', 'langcode'],
        'unique keys' => [],
        'indexes' => [
          'entity_test__id__default_langcode__langcode' => [
555 556 557
            0 => 'id',
            1 => 'default_langcode',
            2 => 'langcode',
558 559 560 561
          ],
        ],
        'foreign keys' => [
          'entity_test' => [
562
            'table' => 'entity_test',
563 564 565 566 567
            'columns' => ['id' => 'id'],
          ],
        ],
      ],
    ];
568

569
    $this->setUpStorageSchema($expected);
570

571
    $table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
572 573 574
    $non_data_fields = array_keys($this->storageDefinitions);
    unset($non_data_fields[array_search('default_langcode', $non_data_fields)]);
    $table_mapping->setFieldNames('entity_test', $non_data_fields);
575 576 577 578 579 580
    $table_mapping->setFieldNames('entity_test_field_data', array_keys($this->storageDefinitions));

    $this->storage->expects($this->any())
      ->method('getTableMapping')
      ->will($this->returnValue($table_mapping));

581 582 583
    $this->assertNull(
      $this->storageSchema->onEntityTypeCreate($this->entityType)
    );
584 585 586 587 588
  }

  /**
   * Tests the schema for revisionable, translatable entities.
   *
589 590 591 592 593 594 595
   * @covers ::__construct
   * @covers ::getEntitySchemaTables
   * @covers ::initializeDataTable
   * @covers ::addTableDefaults
   * @covers ::getEntityIndexName
   * @covers ::initializeRevisionDataTable
   * @covers ::processRevisionDataTable
596 597
   */
  public function testGetSchemaRevisionableTranslatable() {
598
    $this->entityType = new ContentEntityType([
599
      'id' => 'entity_test',
600
      'entity_keys' => [
601 602
        'id' => 'id',
        'revision' => 'revision_id',
603
        'langcode' => 'langcode',
604 605
      ],
    ]);
606 607 608 609 610 611 612 613 614 615 616

    $this->storage->expects($this->exactly(3))
      ->method('getRevisionTable')
      ->will($this->returnValue('entity_test_revision'));
    $this->storage->expects($this->once())
      ->method('getDataTable')
      ->will($this->returnValue('entity_test_field_data'));
    $this->storage->expects($this->once())
      ->method('getRevisionDataTable')
      ->will($this->returnValue('entity_test_revision_field_data'));

617 618 619
    $this->setUpStorageDefinition('revision_id', [
      'columns' => [
        'value' => [
620
          'type' => 'int',
621 622 623 624 625 626
        ],
      ],
    ]);
    $this->setUpStorageDefinition('langcode', [
      'columns' => [
        'value' => [
627
          'type' => 'varchar',
628 629 630 631 632 633
        ],
      ],
    ]);
    $this->setUpStorageDefinition('default_langcode', [
      'columns' => [
        'value' => [
634 635
          'type' => 'int',
          'size' => 'tiny',
636 637 638
        ],
      ],
    ]);
639

640 641
    $expected = [
      'entity_test' => [
642
        'description' => 'The base table for entity_test entities.',
643 644
        'fields' => [
          'id' => [
645 646
            'type' => 'serial',
            'not null' => TRUE,
647 648
          ],
          'revision_id' => [
649
            'type' => 'int',
650
            'not null' => FALSE,
651 652
          ],
          'langcode' => [
653 654
            'type' => 'varchar',
            'not null' => TRUE,
655 656 657 658 659 660 661 662 663
          ]
        ],
        'primary key' => ['id'],
        'unique keys' => [
          'entity_test__revision_id' => ['revision_id'],
        ],
        'indexes' => [],
        'foreign keys' => [
          'entity_test__revision' => [
664
            'table' => 'entity_test_revision',
665 666 667 668 669
            'columns' => ['revision_id' => 'revision_id'],
          ],
        ],
      ],
      'entity_test_revision' => [
670
        'description' => 'The revision table for entity_test entities.',
671 672
        'fields' => [
          'id' => [
673 674
            'type' => 'int',
            'not null' => TRUE,
675 676
          ],
          'revision_id' => [
677
            'type' => 'serial',
678
            'not null' => TRUE,
679 680
          ],
          'langcode' => [
681 682
            'type' => 'varchar',
            'not null' => TRUE,
683 684 685 686 687 688 689 690 691
          ],
        ],
        'primary key' => ['revision_id'],
        'unique keys' => [],
        'indexes' => [
          'entity_test__id' => ['id'],
        ],
        'foreign keys' => [
          'entity_test__revisioned' => [
692
            'table' => 'entity_test',
693 694 695 696 697
            'columns' => ['id' => 'id'],
          ],
        ],
      ],
      'entity_test_field_data' => [
698
        'description' => 'The data table for entity_test entities.',
699 700
        'fields' => [
          'id' => [
701 702
            'type' => 'int',
            'not null' => TRUE,
703 704
          ],
          'revision_id' => [
705
            'type' => 'int',
706
            'not null' => TRUE,
707 708
          ],
          'langcode' => [
709 710
            'type' => 'varchar',
            'not null' => TRUE,
711 712
          ],
          'default_langcode' => [
713 714
            'type' => 'int',
            'size' => 'tiny',
715
            'not null' => TRUE,
716 717 718 719 720 721 722
          ],
        ],
        'primary key' => ['id', 'langcode'],
        'unique keys' => [],
        'indexes' => [
          'entity_test__revision_id' => ['revision_id'],
          'entity_test__id__default_langcode__langcode' => [
723 724 725
            0 => 'id',
            1 => 'default_langcode',
            2 => 'langcode',
726 727 728 729
          ],
        ],
        'foreign keys' => [
          'entity_test' => [
730
            'table' => 'entity_test',
731 732 733 734 735
            'columns' => ['id' => 'id'],
          ],
        ],
      ],
      'entity_test_revision_field_data' => [
736
        'description' => 'The revision data table for entity_test entities.',
737 738
        'fields' => [
          'id' => [
739 740
            'type' => 'int',
            'not null' => TRUE,
741 742
          ],
          'revision_id' => [
743
            'type' => 'int',
744
            'not null' => TRUE,
745 746
          ],
          'langcode' => [
747 748
            'type' => 'varchar',
            'not null' => TRUE,
749 750
          ],
          'default_langcode' => [
751 752
            'type' => 'int',
            'size' => 'tiny',
753
            'not null' => TRUE,
754 755 756 757 758 759
          ],
        ],
        'primary key' => ['revision_id', 'langcode'],
        'unique keys' => [],
        'indexes' => [
          'entity_test__id__default_langcode__langcode' => [
760 761 762
            0 => 'id',
            1 => 'default_langcode',
            2 => 'langcode',
763 764 765 766
          ],
        ],
        'foreign keys' => [
          'entity_test' => [
767
            'table' => 'entity_test',
768 769 770
            'columns' => ['id' => 'id'],
          ],
          'entity_test__revision' => [
771
            'table' => 'entity_test_revision',
772 773 774 775 776
            'columns' => ['revision_id' => 'revision_id'],
          ],
        ],
      ],
    ];
777

778
    $this->setUpStorageSchema($expected);
779

780
    $table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
781 782 783 784
    $non_data_fields = array_keys($this->storageDefinitions);
    unset($non_data_fields[array_search('default_langcode', $non_data_fields)]);
    $table_mapping->setFieldNames('entity_test', $non_data_fields);
    $table_mapping->setFieldNames('entity_test_revision', $non_data_fields);
785 786 787 788 789 790 791
    $table_mapping->setFieldNames('entity_test_field_data', array_keys($this->storageDefinitions));
    $table_mapping->setFieldNames('entity_test_revision_field_data', array_keys($this->storageDefinitions));

    $this->storage->expects($this->any())
      ->method('getTableMapping')
      ->will($this->returnValue($table_mapping));

792 793 794 795 796 797
    $this->storageSchema->onEntityTypeCreate($this->entityType);
  }

  /**
   * Tests the schema for a field dedicated table.
   *
798
   * @covers ::onFieldStorageDefinitionCreate
799 800
   * @covers ::getDedicatedTableSchema
   * @covers ::createDedicatedTableSchema
801 802 803
   */
  public function testDedicatedTableSchema() {
    $entity_type_id = 'entity_test';
804
    $this->entityType = new ContentEntityType([
805
      'id' => 'entity_test',
806 807
      'entity_keys' => ['id' => 'id'],
    ]);
808 809 810

    // Setup a field having a dedicated schema.
    $field_name = $this->getRandomGenerator()->name();
811 812 813
    $this->setUpStorageDefinition($field_name, [
      'columns' => [
        'shape' => [
814 815 816
          'type' => 'varchar',
          'length' => 32,
          'not null' => FALSE,
817 818
        ],
        'color' => [
819 820 821
          'type' => 'varchar',
          'length' => 32,
          'not null' => FALSE,
822 823
        ],
        'area' => [
824 825 826
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
827 828
        ],
        'depth' => [
829 830 831
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
832 833 834 835
        ],
      ],
      'foreign keys' => [
        'color' => [
836
          'table' => 'color',
837
          'columns' => [
838
            'color' => 'id'
839 840 841 842 843 844 845 846 847 848 849 850
          ],
        ],
      ],
      'unique keys' => [
        'area' => ['area'],
        'shape' => [['shape', 10]],
      ],
      'indexes' => [
        'depth' => ['depth'],
        'color' => [['color', 3]],
      ],
    ]);
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870

    $field_storage = $this->storageDefinitions[$field_name];
    $field_storage
      ->expects($this->any())
      ->method('getType')
      ->will($this->returnValue('shape'));
    $field_storage
      ->expects($this->any())
      ->method('getTargetEntityTypeId')
      ->will($this->returnValue($entity_type_id));
    $field_storage
      ->expects($this->any())
      ->method('isMultiple')
      ->will($this->returnValue(TRUE));

    $this->storageDefinitions['id']
      ->expects($this->any())
      ->method('getType')
      ->will($this->returnValue('integer'));

871 872
    $expected = [
      $entity_type_id . '__' . $field_name => [
873
        'description' => "Data storage for $entity_type_id field $field_name.",
874 875
        'fields' => [
          'bundle' => [
876
            'type' => 'varchar_ascii',
877
            'length' => 128,
878
            'not null' => TRUE,
879 880
            'default' => '',
            'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance',
881 882
          ],
          'deleted' => [
883 884
            'type' => 'int',
            'size' => 'tiny',
885
            'not null' => TRUE,
886 887
            'default' => 0,
            'description' => 'A boolean indicating whether this data item has been deleted',
888 889
          ],
          'entity_id' => [
890
            'type' => 'int',
891 892
            'unsigned' => TRUE,
            'not null' => TRUE,
893
            'description' => 'The entity id this data is attached to',
894 895
          ],
          'revision_id' => [
896
            'type' => 'int',
897 898
            'unsigned' => TRUE,
            'not null' => TRUE,
899
            'description' => 'The entity revision id this data is attached to, which for an unversioned entity type is the same as the entity id',
900