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\simpletest\ContentTypeCreationTrait;
13 use Drupal\simpletest\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 $node = Node::create(array(
106 'title' => $this->randomMachineName(),
108 'composite_reference' => $composite,
112 // Assert that there is only 1 revision when creating a node.
113 $node_revisions_count = \Drupal::entityQuery('node')->condition('nid', $node->id())->allRevisions()->count()->execute();
114 $this->assertEqual($node_revisions_count, 1);
115 // Assert there is no new composite revision after creating a host entity.
116 $composite_revisions_count = \Drupal::entityQuery('entity_test_composite')->condition('uuid', $composite->uuid())->allRevisions()->count()->execute();
117 $this->assertEquals(1, $composite_revisions_count);
119 // Verify the value of parent type and id after create a node.
120 $composite = EntityTestCompositeRelationship::load($composite->id());
121 $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
122 $this->assertEqual($composite->parent_id->value, $node->id());
123 $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
124 // Create second revision of the node.
125 $original_composite_revision = $node->composite_reference[0]->target_revision_id;
126 $original_node_revision = $node->getRevisionId();
127 $node->setTitle('2nd revision');
128 $node->setNewRevision();
130 $node = node_load($node->id(), TRUE);
131 // Check the revision of the node.
132 $this->assertEqual('2nd revision', $node->getTitle(), 'New node revision has changed data.');
133 $this->assertNotEqual($original_composite_revision, $node->composite_reference[0]->target_revision_id, 'Composite entity got new revision when its host did.');
135 // Make sure that there are only 2 revisions.
136 $node_revisions_count = \Drupal::entityQuery('node')->condition('nid', $node->id())->allRevisions()->count()->execute();
137 $this->assertEqual($node_revisions_count, 2);
139 // Revert to first revision of the node.
140 $node = $this->entityTypeManager->getStorage('node')->loadRevision($original_node_revision);
141 $node->setNewRevision();
142 $node->isDefaultRevision(TRUE);
144 $node = node_load($node->id(), TRUE);
145 // Check the revision of the node.
146 $this->assertNotEqual('2nd revision', $node->getTitle(), 'Node did not keep changed title after reversion.');
147 $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.');
149 // Test that the composite entity is deleted when its parent is deleted.
151 $this->assertNull(EntityTestCompositeRelationship::load($composite->id()));
155 * Tests composite relationship with translations and an untranslatable field.
157 function testCompositeRelationshipWithTranslationNonTranslatableField() {
159 ConfigurableLanguage::createFromLangcode('de')->save();
161 // Create the test composite entity with a translation.
162 $composite = EntityTestCompositeRelationship::create(array(
163 'uuid' => $this->randomMachineName(),
164 'name' => $this->randomMachineName(),
166 $composite->addTranslation('de', $composite->toArray());
170 // Create a node with a reference to the test composite entity.
171 $node = Node::create(array(
172 'title' => $this->randomMachineName(),
174 'composite_reference' => $composite,
176 $node->addTranslation('de', $node->toArray());
179 // Verify the value of parent type and id after create a node.
180 $composite = EntityTestCompositeRelationship::load($composite->id());
181 $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
182 $this->assertEqual($composite->parent_id->value, $node->id());
183 $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
184 $this->assertTrue($composite->hasTranslation('de'));
186 // Test that the composite entity is not when the german translation of the
187 // parent is deleted.
188 $node->removeTranslation('de');
190 $composite = EntityTestCompositeRelationship::load($composite->id());
191 $this->assertNotNull($composite);
192 // @todo Support deleting translations of a composite reference.
193 // @see https://www.drupal.org/node/2834314.
194 //$this->assertFalse($composite->hasTranslation('de'));
196 // Test that the composite entity is deleted when its parent is deleted.
198 $composite = EntityTestCompositeRelationship::load($composite->id());
199 $this->assertNull($composite);
203 * Tests composite relationship with translations and a translatable field.
205 function testCompositeRelationshipWithTranslationTranslatableField() {
206 $field_config = FieldConfig::loadByName('node', 'article', 'composite_reference');
207 $field_config->setTranslatable(TRUE);
208 $field_config->save();
210 ConfigurableLanguage::createFromLangcode('de')->save();
212 // Create the test composite entity with a translation.
213 $composite = EntityTestCompositeRelationship::create(array(
214 'uuid' => $this->randomMachineName(),
215 'name' => $this->randomMachineName(),
217 $composite->addTranslation('de', $composite->toArray());
220 // Create a node with a reference to the test composite entity.
221 $node = Node::create(array(
222 'title' => $this->randomMachineName(),
224 'composite_reference' => $composite,
226 $node->addTranslation('de', $node->toArray());
229 // Verify the value of parent type and id after create a node.
230 $composite = EntityTestCompositeRelationship::load($composite->id());
231 $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
232 $this->assertEqual($composite->parent_id->value, $node->id());
233 $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
235 // Test that the composite entity is not when the german translation of the parent is deleted.
236 $node->removeTranslation('de');
238 //$this->entityTypeManager->getStorage('entity_test_composite')->resetCache();
239 $composite = EntityTestCompositeRelationship::load($composite->id());
240 $this->assertNotNull($composite);
242 // Test that the composite entity is deleted when its parent is deleted.
244 $composite = EntityTestCompositeRelationship::load($composite->id());
245 // @todo Support deletions for translatable fields.
246 // @see https://www.drupal.org/node/2834374
247 // $this->assertNull($composite);
251 * Tests composite relationship with revisions.
253 function testCompositeRelationshipWithRevisions() {
255 // Create the test composite entity with a translation.
256 $composite = EntityTestCompositeRelationship::create(array(
257 'uuid' => $this->randomMachineName(),
258 'name' => $this->randomMachineName(),
262 // Create a node with a reference to the test composite entity.
263 $node = Node::create(array(
264 'title' => $this->randomMachineName(),
266 'composite_reference' => $composite,
271 // Verify the value of parent type and id after create a node.
272 $composite = EntityTestCompositeRelationship::load($composite->id());
273 $composite_original_revision_id = $composite->getRevisionId();
274 $node_original_revision_id = $node->getRevisionId();
275 $this->assertEqual($composite->parent_type->value, $node->getEntityTypeId());
276 $this->assertEqual($composite->parent_id->value, $node->id());
277 $this->assertEqual($composite->parent_field_name->value, 'composite_reference');
279 $node->setNewRevision(TRUE);
281 // Ensure that we saved a new revision ID.
282 $composite = EntityTestCompositeRelationship::load($composite->id());
283 $this->assertNotEqual($composite->getRevisionId(), $composite_original_revision_id);
285 // Test that deleting the first revision does not delete the composite.
286 $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
287 $composite = EntityTestCompositeRelationship::load($composite->id());
288 $this->assertNotNull($composite);
290 // Ensure that the composite revision was deleted as well.
291 $composite_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
292 $this->assertNull($composite_revision);
294 // Test that the composite entity is deleted when its parent is deleted.
296 $composite = EntityTestCompositeRelationship::load($composite->id());
297 $this->assertNull($composite);
301 * Tests that the composite revision is not deleted if it is the default one.
303 function testCompositeRelationshipDefaultRevision() {
304 // Create a node with a reference to a test composite entity.
305 $composite = EntityTestCompositeRelationship::create([
306 'uuid' => $this->randomMachineName(),
307 'name' => $this->randomMachineName(),
310 $node = Node::create([
311 'title' => $this->randomMachineName(),
313 'composite_reference' => $composite,
317 $composite = EntityTestCompositeRelationship::load($composite->id());
318 $composite_original_revision_id = $composite->getRevisionId();
319 $node_original_revision_id = $node->getRevisionId();
321 // Set a new revision, composite entity should have a new revision as well.
322 $node->setNewRevision(TRUE);
324 // Ensure that we saved a new revision ID.
325 $composite2 = EntityTestCompositeRelationship::load($composite->id());
326 $composite2_rev_id = $composite2->getRevisionId();
327 $this->assertNotEquals($composite2_rev_id, $composite_original_revision_id);
329 // Revert default composite entity revision to the original revision.
330 $composite_original = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
331 $composite_original->isDefaultRevision(TRUE);
332 $composite_original->save();
333 // Check the default composite revision is the original composite revision.
334 $this->assertEquals($composite_original_revision_id, $composite_original->getrevisionId());
336 // Test deleting the first node revision, referencing to the default
337 // composite revision, does not delete the default composite revision.
338 $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
339 $composite_default = EntityTestCompositeRelationship::load($composite_original->id());
340 $this->assertNotNull($composite_default);
341 $composite_default_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original->getrevisionId());
342 $this->assertNotNull($composite_default_revision);
343 // Ensure the second revision still exists.
344 $composite2_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite2_rev_id);
345 $this->assertNotNull($composite2_revision);
349 * Tests that the composite revision is not deleted if it is still in use.
351 function testCompositeRelationshipDuplicatedRevisions() {
352 // Create a node with a reference to a test composite entity.
353 $composite = EntityTestCompositeRelationship::create([
354 'uuid' => $this->randomMachineName(),
355 'name' => $this->randomMachineName(),
358 $node = Node::create([
359 'title' => $this->randomMachineName(),
361 'composite_reference' => $composite,
365 $composite = EntityTestCompositeRelationship::load($composite->id());
366 $composite_original_revision_id = $composite->getRevisionId();
367 $node_original_revision_id = $node->getRevisionId();
369 // Set a new revision, composite entity should have a new revision as well.
370 $node->setNewRevision(TRUE);
372 // Ensure that we saved a new revision ID.
373 $composite2 = EntityTestCompositeRelationship::load($composite->id());
374 $composite2_rev_id = $composite2->getRevisionId();
375 $this->assertNotEquals($composite2_rev_id, $composite_original_revision_id);
377 // Set the new node revision to reference to the original composite
378 // revision as well to test this composite revision will not be deleted.
379 $this->database->update('node__composite_reference')
380 ->fields(['composite_reference_target_revision_id' => $composite_original_revision_id])
381 ->condition('revision_id', $node->getRevisionId())
383 $this->database->update('node_revision__composite_reference')
384 ->fields(['composite_reference_target_revision_id' => $composite_original_revision_id])
385 ->condition('revision_id', $node->getRevisionId())
388 // Test deleting the first revision does not delete the composite.
389 $this->entityTypeManager->getStorage('node')->deleteRevision($node_original_revision_id);
390 $composite2 = EntityTestCompositeRelationship::load($composite2->id());
391 $this->assertNotNull($composite2);
393 // Ensure the original composite revision is not deleted because it is
394 // still referenced by the second node revision.
395 $composite_original_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite_original_revision_id);
396 $this->assertNotNull($composite_original_revision);
397 // Ensure the second revision still exists.
398 $composite2_revision = $this->entityTypeManager->getStorage('entity_test_composite')->loadRevision($composite2_rev_id);
399 $this->assertNotNull($composite2_revision);
401 // Test that the composite entity is deleted when its parent is deleted.
403 $composite = EntityTestCompositeRelationship::load($composite2->id());
404 $this->assertNull($composite);