3 namespace Drupal\KernelTests\Core\Entity;
5 use Drupal\Core\Entity\EntityStorageException;
6 use Drupal\entity_test\Entity\EntityTest;
7 use Drupal\user\UserInterface;
10 * Tests basic CRUD functionality.
14 class EntityApiTest extends EntityKernelTestBase {
19 protected function setUp() {
22 foreach (entity_test_entity_types() as $entity_type_id) {
23 // The entity_test schema is installed by the parent.
24 if ($entity_type_id != 'entity_test') {
25 $this->installEntitySchema($entity_type_id);
31 * Tests basic CRUD functionality of the Entity API.
33 public function testCRUD() {
34 // All entity variations have to have the same results.
35 foreach (entity_test_entity_types() as $entity_type) {
36 $this->assertCRUD($entity_type, $this->createUser());
41 * Executes a test set for a defined entity type and user.
43 * @param string $entity_type
44 * The entity type to run the tests with.
45 * @param \Drupal\user\UserInterface $user1
46 * The user to run the tests with.
48 protected function assertCRUD($entity_type, UserInterface $user1) {
49 // Create some test entities.
50 $entity = $this->container->get('entity_type.manager')
51 ->getStorage($entity_type)
52 ->create(['name' => 'test', 'user_id' => $user1->id()]);
54 $entity = $this->container->get('entity_type.manager')
55 ->getStorage($entity_type)
56 ->create(['name' => 'test2', 'user_id' => $user1->id()]);
58 $entity = $this->container->get('entity_type.manager')
59 ->getStorage($entity_type)
60 ->create(['name' => 'test', 'user_id' => NULL]);
63 /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
64 $storage = $this->container->get('entity_type.manager')
65 ->getStorage($entity_type);
67 $entities = array_values($storage->loadByProperties(['name' => 'test']));
68 $this->assertEqual($entities[0]->name->value, 'test', format_string('%entity_type: Created and loaded entity', ['%entity_type' => $entity_type]));
69 $this->assertEqual($entities[1]->name->value, 'test', format_string('%entity_type: Created and loaded entity', ['%entity_type' => $entity_type]));
71 // Test loading a single entity.
72 $loaded_entity = $storage->load($entity->id());
73 $this->assertEqual($loaded_entity->id(), $entity->id(), format_string('%entity_type: Loaded a single entity by id.', ['%entity_type' => $entity_type]));
75 // Test deleting an entity.
76 $entities = array_values($storage->loadByProperties(['name' => 'test2']));
77 $entities[0]->delete();
78 $entities = array_values($storage->loadByProperties(['name' => 'test2']));
79 $this->assertEqual($entities, [], format_string('%entity_type: Entity deleted.', ['%entity_type' => $entity_type]));
81 // Test updating an entity.
82 $entities = array_values($storage->loadByProperties(['name' => 'test']));
83 $entities[0]->name->value = 'test3';
85 $entity = $storage->load($entities[0]->id());
86 $this->assertEqual($entity->name->value, 'test3', format_string('%entity_type: Entity updated.', ['%entity_type' => $entity_type]));
88 // Try deleting multiple test entities by deleting all.
89 $ids = array_keys($storage->loadMultiple());
90 entity_delete_multiple($entity_type, $ids);
92 $all = $storage->loadMultiple();
93 $this->assertTrue(empty($all), format_string('%entity_type: Deleted all entities.', ['%entity_type' => $entity_type]));
95 // Verify that all data got deleted.
96 $definition = \Drupal::entityManager()->getDefinition($entity_type);
97 $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $definition->getBaseTable() . '}')->fetchField(), 'Base table was emptied');
98 if ($data_table = $definition->getDataTable()) {
99 $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $data_table . '}')->fetchField(), 'Data table was emptied');
101 if ($revision_table = $definition->getRevisionTable()) {
102 $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $revision_table . '}')->fetchField(), 'Data table was emptied');
104 if ($revision_data_table = $definition->getRevisionDataTable()) {
105 $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $revision_data_table . '}')->fetchField(), 'Data table was emptied');
108 // Test deleting a list of entities not indexed by entity id.
110 $entity = entity_create($entity_type, ['name' => 'test', 'user_id' => $user1->id()]);
112 $entities['test'] = $entity;
113 $entity = entity_create($entity_type, ['name' => 'test2', 'user_id' => $user1->id()]);
115 $entities['test2'] = $entity;
116 $controller = \Drupal::entityManager()->getStorage($entity_type);
117 $controller->delete($entities);
119 // Verify that entities got deleted.
120 $all = $storage->loadMultiple();
121 $this->assertTrue(empty($all), format_string('%entity_type: Deleted all entities.', ['%entity_type' => $entity_type]));
123 // Verify that all data got deleted from the tables.
124 $definition = \Drupal::entityManager()->getDefinition($entity_type);
125 $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $definition->getBaseTable() . '}')->fetchField(), 'Base table was emptied');
126 if ($data_table = $definition->getDataTable()) {
127 $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $data_table . '}')->fetchField(), 'Data table was emptied');
129 if ($revision_table = $definition->getRevisionTable()) {
130 $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $revision_table . '}')->fetchField(), 'Data table was emptied');
132 if ($revision_data_table = $definition->getRevisionDataTable()) {
133 $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $revision_data_table . '}')->fetchField(), 'Data table was emptied');
138 * Tests that exceptions are thrown when saving or deleting an entity.
140 public function testEntityStorageExceptionHandling() {
141 $entity = EntityTest::create(['name' => 'test']);
143 $GLOBALS['entity_test_throw_exception'] = TRUE;
145 $this->fail('Entity presave EntityStorageException thrown but not caught.');
147 catch (EntityStorageException $e) {
148 $this->assertEqual($e->getcode(), 1, 'Entity presave EntityStorageException caught.');
151 $entity = EntityTest::create(['name' => 'test2']);
153 unset($GLOBALS['entity_test_throw_exception']);
155 $this->pass('Exception presave not thrown and not caught.');
157 catch (EntityStorageException $e) {
158 $this->assertNotEqual($e->getCode(), 1, 'Entity presave EntityStorageException caught.');
161 $entity = EntityTest::create(['name' => 'test3']);
164 $GLOBALS['entity_test_throw_exception'] = TRUE;
166 $this->fail('Entity predelete EntityStorageException not thrown.');
168 catch (EntityStorageException $e) {
169 $this->assertEqual($e->getCode(), 2, 'Entity predelete EntityStorageException caught.');
172 unset($GLOBALS['entity_test_throw_exception']);
173 $entity = EntityTest::create(['name' => 'test4']);
177 $this->pass('Entity predelete EntityStorageException not thrown and not caught.');
179 catch (EntityStorageException $e) {
180 $this->assertNotEqual($e->getCode(), 2, 'Entity predelete EntityStorageException thrown.');
185 * Tests that resaving a revision with a different revision ID throws an exception.
187 public function testUpdateWithRevisionId() {
188 $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev');
190 // Create a new entity.
191 /** @var \Drupal\entity_test\Entity\EntityTestMulRev $entity */
192 $entity = $storage->create(['name' => 'revision_test']);
195 $this->setExpectedException(EntityStorageException::class, "Update existing 'entity_test_mulrev' entity revision while changing the revision ID is not supported.");
197 $entity->revision_id = 60;
202 * Tests that resaving an entity with a different entity ID throws an exception.
204 public function testUpdateWithId() {
205 $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev');
207 // Create a new entity.
208 /** @var \Drupal\entity_test\Entity\EntityTestMulRev $entity */
209 $entity = $storage->create(['name' => 'revision_test']);
212 $this->setExpectedException(EntityStorageException::class, "Update existing 'entity_test_mulrev' entity while changing the ID is not supported.");