3 namespace Drupal\Tests\entity_reference_revisions\Kernel;
5 use Drupal\entity_composite_relationship_test\Entity\EntityTestCompositeRelationship;
6 use Drupal\field\Entity\FieldConfig;
7 use Drupal\field\Entity\FieldStorageConfig;
8 use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
9 use Drupal\language\Entity\ConfigurableLanguage;
10 use Drupal\node\Entity\Node;
11 use Drupal\node\Entity\NodeType;
12 use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
13 use Drupal\Tests\node\Traits\NodeCreationTrait;
16 * Tests the entity_reference_revisions composite relationship.
18 * @group entity_reference_revisions
20 class EntityReferenceRevisionsCompositeTest extends EntityKernelTestBase {
22 use ContentTypeCreationTrait;
23 use NodeCreationTrait;
30 public static $modules = array(
33 'entity_reference_revisions',
34 'entity_composite_relationship_test',
39 * The current database connection.
41 * @var \Drupal\Core\Database\Connection
46 * The entity type manager.
48 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
51 protected $entityTypeManager;
56 protected function setUp() {
59 $this->installEntitySchema('entity_test_composite');
60 $this->installSchema('node', ['node_access']);
62 // Create article content type.
63 NodeType::create(['type' => 'article', 'name' => 'Article'])->save();
65 // Create the reference to the composite entity test.
66 $field_storage = FieldStorageConfig::create(array(
67 'field_name' => 'composite_reference',
68 'entity_type' => 'node',
69 'type' => 'entity_reference_revisions',
71 'target_type' => 'entity_test_composite'
74 $field_storage->save();
75 $field = FieldConfig::create(array(
76 'field_storage' => $field_storage,
77 'bundle' => 'article',
78 'translatable' => FALSE,
82 // Inject database connection and entity type manager for the tests.
83 $this->database = \Drupal::database();
84 $this->entityTypeManager = \Drupal::entityTypeManager();
88 * Test for maintaining composite relationship.
90 * Tests that the referenced entity saves the parent type and id when saving.
92 public function testEntityReferenceRevisionsCompositeRelationship() {
93 // Create the test composite entity.
94 $composite = EntityTestCompositeRelationship::create(array(
95 'uuid' => $this->randomMachineName(),
96 'name' => $this->randomMachineName(),
100 // Assert that there is only 1 revision of the composite entity.
101 $composite_revisions_count = \Drupal::entityQuery('entity_test_composite')->condition('uuid', $composite->uuid())->allRevisions()->count()->execute();
102 $this->assertEquals(1, $composite_revisions_count);
104 // Create a node with a reference to the test composite entity.
105 /** @var \Drupal\node\NodeInterface $node */
106 $node = Node::create(array(
107 'title' => $this->randomMachineName(),
111 $node->set('composite_reference', $composite);
112 $this->assertTrue($node->hasTranslationChanges());
115 // Assert that there is only 1 revision when creating a node.
116 $node_revisions_count = \Drupal::entityQuery('node')->condition('nid', $node->id())->allRevisions()->count()->execute();
117 $this->assertEqual($node_revisions_count, 1);
118 // Assert there is no new composite revision after creating a host entity.
119 $composite_revisions_count = \Drupal::entityQuery('entity_test_composite')->condition('uuid', $composite->uuid())->allRevisions()->count()->execute();
120 $this->assertEquals(1, $composite_revisions_count);
122 // Verify the value of parent type and id after create a node.
123 $composite = EntityTestCompositeRelationship::load($composite->id());
124 $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
125 $this->assertEqual($composite->parent_id->value, $node->id());
126 $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
127 // Create second revision of the node.
128 $original_composite_revision = $node->composite_reference[0]->target_revision_id;
129 $original_node_revision = $node->getRevisionId();
130 $node->setTitle('2nd revision');
131 $node->setNewRevision();
133 $node = node_load($node->id(), TRUE);
134 // Check the revision of the node.
135 $this->assertEqual('2nd revision', $node->getTitle(), 'New node revision has changed data.');
136 $this->assertNotEqual($original_composite_revision, $node->composite_reference[0]->target_revision_id, 'Composite entity got new revision when its host did.');
138 // Make sure that there are only 2 revisions.
139 $node_revisions_count = \Drupal::entityQuery('node')->condition('nid', $node->id())->allRevisions()->count()->execute();
140 $this->assertEqual($node_revisions_count, 2);
142 // Revert to first revision of the node.
143 $node = $this->entityTypeManager->getStorage('node')->loadRevision($original_node_revision);
144 $node->setNewRevision();
145 $node->isDefaultRevision(TRUE);
147 $node = node_load($node->id(), TRUE);
148 // Check the revision of the node.
149 $this->assertNotEqual('2nd revision', $node->getTitle(), 'Node did not keep changed title after reversion.');
150 $this->assertNotEqual($original_composite_revision, $node->composite_reference[0]->target_revision_id, 'Composite entity got new revision when its host reverted to an old revision.');
152 // Test that removing/changing composite references results in translation
154 $node->set('composite_reference', []);
155 $this->assertTrue($node->hasTranslationChanges());
157 // Revert the changes to avoid interfering with the delete test.
158 $node->set('composite_reference', $composite);
160 // Test that the composite entity is deleted when its parent is deleted.
162 $this->assertNull(EntityTestCompositeRelationship::load($composite->id()));
166 * Tests composite relationship with translations and an untranslatable field.
168 function testCompositeRelationshipWithTranslationNonTranslatableField() {
170 ConfigurableLanguage::createFromLangcode('de')->save();
172 // Create the test composite entity with a translation.
173 $composite = EntityTestCompositeRelationship::create(array(
174 'uuid' => $this->randomMachineName(),
175 'name' => $this->randomMachineName(),
177 $composite->addTranslation('de', $composite->toArray());
181 // Create a node with a reference to the test composite entity.
182 $node = Node::create(array(
183 'title' => $this->randomMachineName(),
185 'composite_reference' => $composite,
187 $node->addTranslation('de', $node->toArray());
190 // Verify the value of parent type and id after create a node.
191 $composite = EntityTestCompositeRelationship::load($composite->id());
192 $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
193 $this->assertEqual($composite->parent_id->value, $node->id());
194 $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
195 $this->assertTrue($composite->hasTranslation('de'));
197 // Test that the composite entity is not deleted when the german translation
198 // of the parent is deleted.
199 $node->removeTranslation('de');
201 $composite = EntityTestCompositeRelationship::load($composite->id());
202 $this->assertNotNull($composite);
203 $this->assertFalse($composite->hasTranslation('de'));
205 // Change the language of the entity, ensure that doesn't try to delete
206 // the default translation.
207 $node->set('langcode', 'de');
209 $composite = EntityTestCompositeRelationship::load($composite->id());
210 $this->assertNotNull($composite);
212 // Test that the composite entity is deleted when its parent is deleted.
214 $composite = EntityTestCompositeRelationship::load($composite->id());
215 $this->assertNull($composite);
219 * Tests composite relationship with translations and a translatable field.
221 function testCompositeRelationshipWithTranslationTranslatableField() {
222 $field_config = FieldConfig::loadByName('node', 'article', 'composite_reference');
223 $field_config->setTranslatable(TRUE);
224 $field_config->save();
226 ConfigurableLanguage::createFromLangcode('de')->save();
228 // Create the test composite entity with a translation.
229 $composite = EntityTestCompositeRelationship::create(array(
230 'uuid' => $this->randomMachineName(),
231 'name' => $this->randomMachineName(),
233 $composite->addTranslation('de', $composite->toArray());
236 // Create a node with a reference to the test composite entity.
237 $node = Node::create(array(
238 'title' => $this->randomMachineName(),
240 'composite_reference' => $composite,
242 $node->addTranslation('de', $node->toArray());
245 // Verify the value of parent type and id after create a node.
246 $composite = EntityTestCompositeRelationship::load($composite->id());
247 $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
248 $this->assertEqual($composite->parent_id->value, $node->id());
249 $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
251 // Test that the composite entity is not when the german translation of the parent is deleted.
252 $node->removeTranslation('de');
254 //$this->entityTypeManager->getStorage('entity_test_composite')->resetCache();
255 $composite = EntityTestCompositeRelationship::load($composite->id());
256 $this->assertNotNull($composite);
258 // Test that the composite entity is deleted when its parent is deleted.
260 $composite = EntityTestCompositeRelationship::load($composite->id());
261 // @todo Support deletions for translatable fields.
262 // @see https://www.drupal.org/node/2834374
263 // $this->assertNull($composite);
267 * Tests composite relationship with revisions.
269 function testCompositeRelationshipWithRevisions() {
271 // Create the test composite entity with a translation.
272 $composite = EntityTestCompositeRelationship::create(array(
273 'uuid' => $this->randomMachineName(),
274 'name' => $this->randomMachineName(),
278 // Create a node with a reference to the test composite entity.
279 $node = Node::create(array(
280 'title' => $this->randomMachineName(),
282 'composite_reference' => $composite,
287 // Verify the value of parent type and id after create a node.
288 $composite = EntityTestCompositeRelationship::load($composite->id());
289 $composite_original_revision_id = $composite->getRevisionId();
290 $node_original_revision_id = $node->getRevisionId();
291 $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
292 $this->assertEqual($composite->parent_id->value, $node->id());
293 $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
295 $node->setNewRevision(TRUE);
297 // Ensure that we saved a new revision ID.
298 $composite = EntityTestCompositeRelationship::load($composite->id());
299 $this->assertNotEqual($composite->getRevisionId(), $composite_original_revision_id);
301 // Test that deleting the first revision does not delete the composite.
302 $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
303 $composite = EntityTestCompositeRelationship::load($composite->id());
304 $this->assertNotNull($composite);
306 // Ensure that the composite revision was deleted as well.
307 $composite_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
308 $this->assertNull($composite_revision);
310 // Test that the composite entity is deleted when its parent is deleted.
312 $composite = EntityTestCompositeRelationship::load($composite->id());
313 $this->assertNull($composite);
317 * Tests that the composite revision is not deleted if it is the default one.
319 function testCompositeRelationshipDefaultRevision() {
320 // Create a node with a reference to a test composite entity.
321 $composite = EntityTestCompositeRelationship::create([
322 'uuid' => $this->randomMachineName(),
323 'name' => $this->randomMachineName(),
326 $node = Node::create([
327 'title' => $this->randomMachineName(),
329 'composite_reference' => $composite,
333 $composite = EntityTestCompositeRelationship::load($composite->id());
334 $composite_original_revision_id = $composite->getRevisionId();
335 $node_original_revision_id = $node->getRevisionId();
337 // Set a new revision, composite entity should have a new revision as well.
338 $node->setNewRevision(TRUE);
340 // Ensure that we saved a new revision ID.
341 $composite2 = EntityTestCompositeRelationship::load($composite->id());
342 $composite2_rev_id = $composite2->getRevisionId();
343 $this->assertNotEquals($composite2_rev_id, $composite_original_revision_id);
345 // Revert default composite entity revision to the original revision.
346 $composite_original = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
347 $composite_original->isDefaultRevision(TRUE);
348 $composite_original->save();
349 // Check the default composite revision is the original composite revision.
350 $this->assertEquals($composite_original_revision_id, $composite_original->getrevisionId());
352 // Test deleting the first node revision, referencing to the default
353 // composite revision, does not delete the default composite revision.
354 $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
355 $composite_default = EntityTestCompositeRelationship::load($composite_original->id());
356 $this->assertNotNull($composite_default);
357 $composite_default_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original->getrevisionId());
358 $this->assertNotNull($composite_default_revision);
359 // Ensure the second revision still exists.
360 $composite2_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite2_rev_id);
361 $this->assertNotNull($composite2_revision);
365 * Tests that the composite revision is not deleted if it is still in use.
367 function testCompositeRelationshipDuplicatedRevisions() {
368 // Create a node with a reference to a test composite entity.
369 $composite = EntityTestCompositeRelationship::create([
370 'uuid' => $this->randomMachineName(),
371 'name' => $this->randomMachineName(),
374 $node = Node::create([
375 'title' => $this->randomMachineName(),
377 'composite_reference' => $composite,
381 $composite = EntityTestCompositeRelationship::load($composite->id());
382 $composite_original_revision_id = $composite->getRevisionId();
383 $node_original_revision_id = $node->getRevisionId();
385 // Set a new revision, composite entity should have a new revision as well.
386 $node->setNewRevision(TRUE);
388 // Ensure that we saved a new revision ID.
389 $composite2 = EntityTestCompositeRelationship::load($composite->id());
390 $composite2_rev_id = $composite2->getRevisionId();
391 $this->assertNotEquals($composite2_rev_id, $composite_original_revision_id);
393 // Set the new node revision to reference to the original composite
394 // revision as well to test this composite revision will not be deleted.
395 $this->database->update('node__composite_reference')
396 ->fields(['composite_reference_target_revision_id' => $composite_original_revision_id])
397 ->condition('revision_id', $node->getRevisionId())
399 $this->database->update('node_revision__composite_reference')
400 ->fields(['composite_reference_target_revision_id' => $composite_original_revision_id])
401 ->condition('revision_id', $node->getRevisionId())
404 // Test deleting the first revision does not delete the composite.
405 $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
406 $composite2 = EntityTestCompositeRelationship::load($composite2->id());
407 $this->assertNotNull($composite2);
409 // Ensure the original composite revision is not deleted because it is
410 // still referenced by the second node revision.
411 $composite_original_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
412 $this->assertNotNull($composite_original_revision);
413 // Ensure the second revision still exists.
414 $composite2_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite2_rev_id);
415 $this->assertNotNull($composite2_revision);
417 // Test that the composite entity is deleted when its parent is deleted.
419 $composite = EntityTestCompositeRelationship::load($composite2->id());
420 $this->assertNull($composite);