Added Entity and Entity Reference Revisions which got dropped somewhere along the...
[yaffs-website] / web / modules / contrib / entity_reference_revisions / tests / src / Kernel / EntityReferenceRevisionsCompositeTest.php
1 <?php
2
3 namespace Drupal\Tests\entity_reference_revisions\Kernel;
4
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;
14
15 /**
16  * Tests the entity_reference_revisions composite relationship.
17  *
18  * @group entity_reference_revisions
19  */
20 class EntityReferenceRevisionsCompositeTest extends EntityKernelTestBase {
21
22   use ContentTypeCreationTrait;
23   use NodeCreationTrait;
24
25   /**
26    * Modules to enable.
27    *
28    * @var array
29    */
30   public static $modules = array(
31     'node',
32     'field',
33     'entity_reference_revisions',
34     'entity_composite_relationship_test',
35     'language'
36   );
37
38   /**
39    * The current database connection.
40    *
41    * @var \Drupal\Core\Database\Connection
42    */
43   protected $database;
44
45   /**
46    * The entity type manager.
47    *
48    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
49    *
50    */
51   protected $entityTypeManager;
52
53   /**
54    * {@inheritdoc}
55    */
56   protected function setUp() {
57     parent::setUp();
58
59     $this->installEntitySchema('entity_test_composite');
60     $this->installSchema('node', ['node_access']);
61
62     // Create article content type.
63     NodeType::create(['type' => 'article', 'name' => 'Article'])->save();
64
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',
70       'settings' => array(
71         'target_type' => 'entity_test_composite'
72       ),
73     ));
74     $field_storage->save();
75     $field = FieldConfig::create(array(
76       'field_storage' => $field_storage,
77       'bundle' => 'article',
78       'translatable' => FALSE,
79     ));
80     $field->save();
81
82     // Inject database connection and entity type manager for the tests.
83     $this->database = \Drupal::database();
84     $this->entityTypeManager = \Drupal::entityTypeManager();
85   }
86
87   /**
88    * Test for maintaining composite relationship.
89    *
90    * Tests that the referenced entity saves the parent type and id when saving.
91    */
92   public function testEntityReferenceRevisionsCompositeRelationship() {
93     // Create the test composite entity.
94     $composite = EntityTestCompositeRelationship::create(array(
95       'uuid' => $this->randomMachineName(),
96       'name' => $this->randomMachineName(),
97     ));
98     $composite->save();
99
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);
103
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(),
108       'type' => 'article',
109     ));
110     $node->save();
111     $node->set('composite_reference', $composite);
112     $this->assertTrue($node->hasTranslationChanges());
113     $node->save();
114
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);
121
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();
132     $node->save();
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.');
137
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);
141
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);
146     $node->save();
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.');
151
152     // Test that removing/changing composite references results in translation
153     // changes.
154     $node->set('composite_reference', []);
155     $this->assertTrue($node->hasTranslationChanges());
156
157     // Revert the changes to avoid interfering with the delete test.
158     $node->set('composite_reference', $composite);
159
160     // Test that the composite entity is deleted when its parent is deleted.
161     $node->delete();
162     $this->assertNull(EntityTestCompositeRelationship::load($composite->id()));
163   }
164
165   /**
166    * Tests composite relationship with translations and an untranslatable field.
167    */
168   function testCompositeRelationshipWithTranslationNonTranslatableField() {
169
170     ConfigurableLanguage::createFromLangcode('de')->save();
171
172     // Create the test composite entity with a translation.
173     $composite = EntityTestCompositeRelationship::create(array(
174       'uuid' => $this->randomMachineName(),
175       'name' => $this->randomMachineName(),
176     ));
177     $composite->addTranslation('de', $composite->toArray());
178     $composite->save();
179
180
181     // Create a node with a reference to the test composite entity.
182     $node = Node::create(array(
183       'title' => $this->randomMachineName(),
184       'type' => 'article',
185       'composite_reference' => $composite,
186     ));
187     $node->addTranslation('de', $node->toArray());
188     $node->save();
189
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'));
196
197     // Test that the composite entity is not deleted when the german translation
198     // of the parent is deleted.
199     $node->removeTranslation('de');
200     $node->save();
201     $composite = EntityTestCompositeRelationship::load($composite->id());
202     $this->assertNotNull($composite);
203     $this->assertFalse($composite->hasTranslation('de'));
204
205     // Change the language of the entity, ensure that doesn't try to delete
206     // the default translation.
207     $node->set('langcode', 'de');
208     $node->save();
209     $composite = EntityTestCompositeRelationship::load($composite->id());
210     $this->assertNotNull($composite);
211
212     // Test that the composite entity is deleted when its parent is deleted.
213     $node->delete();
214     $composite = EntityTestCompositeRelationship::load($composite->id());
215     $this->assertNull($composite);
216   }
217
218   /**
219    * Tests composite relationship with translations and a translatable field.
220    */
221   function testCompositeRelationshipWithTranslationTranslatableField() {
222     $field_config = FieldConfig::loadByName('node', 'article', 'composite_reference');
223     $field_config->setTranslatable(TRUE);
224     $field_config->save();
225
226     ConfigurableLanguage::createFromLangcode('de')->save();
227
228     // Create the test composite entity with a translation.
229     $composite = EntityTestCompositeRelationship::create(array(
230       'uuid' => $this->randomMachineName(),
231       'name' => $this->randomMachineName(),
232     ));
233     $composite->addTranslation('de', $composite->toArray());
234     $composite->save();
235
236     // Create a node with a reference to the test composite entity.
237     $node = Node::create(array(
238       'title' => $this->randomMachineName(),
239       'type' => 'article',
240       'composite_reference' => $composite,
241     ));
242     $node->addTranslation('de', $node->toArray());
243     $node->save();
244
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');
250
251     // Test that the composite entity is not when the german translation of the parent is deleted.
252     $node->removeTranslation('de');
253     $node->save();
254     //$this->entityTypeManager->getStorage('entity_test_composite')->resetCache();
255     $composite = EntityTestCompositeRelationship::load($composite->id());
256     $this->assertNotNull($composite);
257
258     // Test that the composite entity is deleted when its parent is deleted.
259     $node->delete();
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);
264   }
265
266   /**
267    * Tests composite relationship with revisions.
268    */
269   function testCompositeRelationshipWithRevisions() {
270
271     // Create the test composite entity with a translation.
272     $composite = EntityTestCompositeRelationship::create(array(
273       'uuid' => $this->randomMachineName(),
274       'name' => $this->randomMachineName(),
275     ));
276     $composite->save();
277
278     // Create a node with a reference to the test composite entity.
279     $node = Node::create(array(
280       'title' => $this->randomMachineName(),
281       'type' => 'article',
282       'composite_reference' => $composite,
283     ));
284     $node->save();
285
286
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');
294
295     $node->setNewRevision(TRUE);
296     $node->save();
297     // Ensure that we saved a new revision ID.
298     $composite = EntityTestCompositeRelationship::load($composite->id());
299     $this->assertNotEqual($composite->getRevisionId(), $composite_original_revision_id);
300
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);
305
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);
309
310     // Test that the composite entity is deleted when its parent is deleted.
311     $node->delete();
312     $composite = EntityTestCompositeRelationship::load($composite->id());
313     $this->assertNull($composite);
314   }
315
316   /**
317    * Tests that the composite revision is not deleted if it is the default one.
318    */
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(),
324     ]);
325     $composite->save();
326     $node = Node::create([
327       'title' => $this->randomMachineName(),
328       'type' => 'article',
329       'composite_reference' => $composite,
330     ]);
331     $node->save();
332
333     $composite = EntityTestCompositeRelationship::load($composite->id());
334     $composite_original_revision_id = $composite->getRevisionId();
335     $node_original_revision_id = $node->getRevisionId();
336
337     // Set a new revision, composite entity should have a new revision as well.
338     $node->setNewRevision(TRUE);
339     $node->save();
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);
344
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());
351
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);
362   }
363
364   /**
365    * Tests that the composite revision is not deleted if it is still in use.
366    */
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(),
372     ]);
373     $composite->save();
374     $node = Node::create([
375       'title' => $this->randomMachineName(),
376       'type' => 'article',
377       'composite_reference' => $composite,
378     ]);
379     $node->save();
380
381     $composite = EntityTestCompositeRelationship::load($composite->id());
382     $composite_original_revision_id = $composite->getRevisionId();
383     $node_original_revision_id = $node->getRevisionId();
384
385     // Set a new revision, composite entity should have a new revision as well.
386     $node->setNewRevision(TRUE);
387     $node->save();
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);
392
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())
398       ->execute();
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())
402       ->execute();
403
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);
408
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);
416
417     // Test that the composite entity is deleted when its parent is deleted.
418     $node->delete();
419     $composite = EntityTestCompositeRelationship::load($composite2->id());
420     $this->assertNull($composite);
421   }
422
423 }