e5407fcc968e0bcf4d09ba5e3d666e971121a243
[yaffs-website] / web / core / tests / Drupal / KernelTests / Core / Entity / EntityRevisionsTest.php
1 <?php
2
3 namespace Drupal\KernelTests\Core\Entity;
4
5 use Drupal\entity_test\Entity\EntityTestMulRev;
6 use Drupal\language\Entity\ConfigurableLanguage;
7
8 /**
9  * Tests the loaded Revision of an entity.
10  *
11  * @coversDefaultClass \Drupal\Core\Entity\ContentEntityBase
12  *
13  * @group entity
14  */
15 class EntityRevisionsTest extends EntityKernelTestBase {
16
17   /**
18    * Modules to enable.
19    *
20    * @var array
21    */
22   public static $modules = [
23     'system',
24     'entity_test',
25     'language',
26     'content_translation',
27   ];
28
29   /**
30    * {@inheritdoc}
31    */
32   protected function setUp() {
33     parent::setUp();
34
35     $this->installEntitySchema('entity_test_mulrev');
36   }
37
38   /**
39    * Test getLoadedRevisionId() returns the correct ID throughout the process.
40    */
41   public function testLoadedRevisionId() {
42     // Create a basic EntityTestMulRev entity and save it.
43     $entity = EntityTestMulRev::create();
44     $entity->save();
45
46     // Load the created entity and create a new revision.
47     $loaded = EntityTestMulRev::load($entity->id());
48     $loaded->setNewRevision(TRUE);
49
50     // Before saving, the loaded Revision ID should be the same as the created
51     // entity, not the same as the loaded entity (which does not have a revision
52     // ID yet).
53     $this->assertEquals($entity->getRevisionId(), $loaded->getLoadedRevisionId());
54     $this->assertNotEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
55     $this->assertSame(NULL, $loaded->getRevisionId());
56
57     // After updating the loaded Revision ID the result should be the same.
58     $loaded->updateLoadedRevisionId();
59     $this->assertEquals($entity->getRevisionId(), $loaded->getLoadedRevisionId());
60     $this->assertNotEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
61     $this->assertSame(NULL, $loaded->getRevisionId());
62
63     $loaded->save();
64
65     // In entity_test_entity_update() the loaded Revision ID was stored in
66     // state. This should be the same as we had before calling $loaded->save().
67     /** @var \Drupal\Core\Entity\ContentEntityInterface $loaded_original */
68     $loadedRevisionId = \Drupal::state()->get('entity_test.loadedRevisionId');
69     $this->assertEquals($entity->getRevisionId(), $loadedRevisionId);
70     $this->assertNotEquals($loaded->getRevisionId(), $loadedRevisionId);
71
72     // The revision ID and loaded Revision ID should be different for the two
73     // versions of the entity, but the same for a saved entity.
74     $this->assertNotEquals($loaded->getRevisionId(), $entity->getRevisionId());
75     $this->assertNotEquals($loaded->getLoadedRevisionId(), $entity->getLoadedRevisionId());
76     $this->assertEquals($entity->getRevisionId(), $entity->getLoadedRevisionId());
77     $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
78   }
79
80   /**
81    * Tests the loaded revision ID after an entity re-save, clone and duplicate.
82    */
83   public function testLoadedRevisionIdWithNoNewRevision() {
84     // Create a basic EntityTestMulRev entity and save it.
85     $entity = EntityTestMulRev::create();
86     $entity->save();
87
88     // Load the created entity and create a new revision.
89     $loaded = EntityTestMulRev::load($entity->id());
90     $loaded->setNewRevision(TRUE);
91     $loaded->save();
92
93     // Make a change to the loaded entity.
94     $loaded->set('name', 'dublin');
95
96     // The revision id and loaded Revision id should still be the same.
97     $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
98
99     $loaded->save();
100
101     // After saving, the loaded Revision id set in entity_test_entity_update()
102     // and returned from the entity should be the same as the entity's revision
103     // id because a new revision wasn't created, the existing revision was
104     // updated.
105     $loadedRevisionId = \Drupal::state()->get('entity_test.loadedRevisionId');
106     $this->assertEquals($loaded->getRevisionId(), $loadedRevisionId);
107     $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
108
109     // Creating a clone should keep the loaded Revision ID.
110     $clone = clone $loaded;
111     $this->assertSame($loaded->getLoadedRevisionId(), $clone->getLoadedRevisionId());
112
113     // Creating a duplicate should set a NULL loaded Revision ID.
114     $duplicate = $loaded->createDuplicate();
115     $this->assertSame(NULL, $duplicate->getLoadedRevisionId());
116   }
117
118   /**
119    * Tests the loaded revision ID for translatable entities.
120    */
121   public function testTranslatedLoadedRevisionId() {
122     ConfigurableLanguage::createFromLangcode('fr')->save();
123
124     // Create a basic EntityTestMulRev entity and save it.
125     $entity = EntityTestMulRev::create();
126     $entity->save();
127
128     // Load the created entity and create a new revision.
129     $loaded = EntityTestMulRev::load($entity->id());
130     $loaded->setNewRevision(TRUE);
131     $loaded->save();
132
133     // Check it all works with translations.
134     $french = $loaded->addTranslation('fr');
135     // Adding a revision should return the same for each language.
136     $this->assertEquals($french->getRevisionId(), $french->getLoadedRevisionId());
137     $this->assertEquals($loaded->getRevisionId(), $french->getLoadedRevisionId());
138     $this->assertEquals($loaded->getLoadedRevisionId(), $french->getLoadedRevisionId());
139     $french->save();
140     // After saving nothing should change.
141     $this->assertEquals($french->getRevisionId(), $french->getLoadedRevisionId());
142     $this->assertEquals($loaded->getRevisionId(), $french->getLoadedRevisionId());
143     $this->assertEquals($loaded->getLoadedRevisionId(), $french->getLoadedRevisionId());
144     $first_revision_id = $french->getRevisionId();
145     $french->setNewRevision();
146     // Setting a new revision will reset the loaded Revision ID.
147     $this->assertEquals($first_revision_id, $french->getLoadedRevisionId());
148     $this->assertEquals($first_revision_id, $loaded->getLoadedRevisionId());
149     $this->assertNotEquals($french->getRevisionId(), $french->getLoadedRevisionId());
150     $this->assertGreaterThan($french->getRevisionId(), $french->getLoadedRevisionId());
151     $this->assertNotEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
152     $this->assertGreaterThan($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
153     $french->save();
154     // Saving the new revision will reset the origin revision ID again.
155     $this->assertEquals($french->getRevisionId(), $french->getLoadedRevisionId());
156     $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
157   }
158
159   /**
160    * Tests re-saving the entity in entity_test_entity_insert().
161    */
162   public function testSaveInHookEntityInsert() {
163     // Create an entity which will be saved again in entity_test_entity_insert().
164     $entity = EntityTestMulRev::create(['name' => 'EntityLoadedRevisionTest']);
165     $entity->save();
166     $loadedRevisionId = \Drupal::state()->get('entity_test.loadedRevisionId');
167     $this->assertEquals($entity->getLoadedRevisionId(), $loadedRevisionId);
168     $this->assertEquals($entity->getRevisionId(), $entity->getLoadedRevisionId());
169   }
170
171   /**
172    * Tests that latest revisions are working as expected.
173    *
174    * @covers ::isLatestRevision
175    */
176   public function testIsLatestRevision() {
177     // Create a basic EntityTestMulRev entity and save it.
178     $entity = EntityTestMulRev::create();
179     $entity->save();
180     $this->assertTrue($entity->isLatestRevision());
181
182     // Load the created entity and create a new pending revision.
183     $pending_revision = EntityTestMulRev::load($entity->id());
184     $pending_revision->setNewRevision(TRUE);
185     $pending_revision->isDefaultRevision(FALSE);
186
187     // The pending revision should still be marked as the latest one before it
188     // is saved.
189     $this->assertTrue($pending_revision->isLatestRevision());
190     $pending_revision->save();
191     $this->assertTrue($pending_revision->isLatestRevision());
192
193     // Load the default revision and check that it is not marked as the latest
194     // revision.
195     $default_revision = EntityTestMulRev::load($entity->id());
196     $this->assertFalse($default_revision->isLatestRevision());
197   }
198
199   /**
200    * Tests that latest affected revisions are working as expected.
201    *
202    * The latest revision affecting a particular translation behaves as the
203    * latest revision for monolingual entities.
204    *
205    * @covers ::isLatestTranslationAffectedRevision
206    * @covers \Drupal\Core\Entity\ContentEntityStorageBase::getLatestRevisionId
207    * @covers \Drupal\Core\Entity\ContentEntityStorageBase::getLatestTranslationAffectedRevisionId
208    */
209   public function testIsLatestAffectedRevisionTranslation() {
210     ConfigurableLanguage::createFromLangcode('it')->save();
211
212     // Create a basic EntityTestMulRev entity and save it.
213     $entity = EntityTestMulRev::create();
214     $entity->setName($this->randomString());
215     $entity->save();
216     $this->assertTrue($entity->isLatestTranslationAffectedRevision());
217
218     // Load the created entity and create a new pending revision.
219     $pending_revision = EntityTestMulRev::load($entity->id());
220     $pending_revision->setName($this->randomString());
221     $pending_revision->setNewRevision(TRUE);
222     $pending_revision->isDefaultRevision(FALSE);
223
224     // Check that no revision affecting Italian is available, given that no
225     // Italian translation has been created yet.
226     /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
227     $storage = $this->entityManager->getStorage($entity->getEntityTypeId());
228     $this->assertNull($storage->getLatestTranslationAffectedRevisionId($entity->id(), 'it'));
229     $this->assertEquals($pending_revision->getLoadedRevisionId(), $storage->getLatestRevisionId($entity->id()));
230
231     // The pending revision should still be marked as the latest affected one
232     // before it is saved.
233     $this->assertTrue($pending_revision->isLatestTranslationAffectedRevision());
234     $pending_revision->save();
235     $this->assertTrue($pending_revision->isLatestTranslationAffectedRevision());
236
237     // Load the default revision and check that it is not marked as the latest
238     // (translation-affected) revision.
239     $default_revision = EntityTestMulRev::load($entity->id());
240     $this->assertFalse($default_revision->isLatestRevision());
241     $this->assertFalse($default_revision->isLatestTranslationAffectedRevision());
242
243     // Add a translation in a new pending revision and verify that both the
244     // English and Italian revision translations are the latest affected
245     // revisions for their respective languages, while the English revision is
246     // not the latest revision.
247     /** @var \Drupal\entity_test\Entity\EntityTestMulRev $en_revision */
248     $en_revision = clone $pending_revision;
249     /** @var \Drupal\entity_test\Entity\EntityTestMulRev $it_revision */
250     $it_revision = $pending_revision->addTranslation('it');
251     $it_revision->setName($this->randomString());
252     $it_revision->setNewRevision(TRUE);
253     $it_revision->isDefaultRevision(FALSE);
254     // @todo Remove this once the "original" property works with revisions. See
255     //   https://www.drupal.org/project/drupal/issues/2859042.
256     $it_revision->original = $storage->loadRevision($it_revision->getLoadedRevisionId());
257     $it_revision->save();
258     $this->assertTrue($it_revision->isLatestRevision());
259     $this->assertTrue($it_revision->isLatestTranslationAffectedRevision());
260     $this->assertFalse($en_revision->isLatestRevision());
261     $this->assertTrue($en_revision->isLatestTranslationAffectedRevision());
262   }
263
264 }