3 namespace Drupal\KernelTests\Core\Entity;
5 use Drupal\entity_test\Entity\EntityTestMulRev;
6 use Drupal\language\Entity\ConfigurableLanguage;
9 * Tests the loaded Revision of an entity.
11 * @coversDefaultClass \Drupal\Core\Entity\ContentEntityBase
15 class EntityRevisionsTest extends EntityKernelTestBase {
22 public static $modules = [
26 'content_translation',
32 protected function setUp() {
35 $this->installEntitySchema('entity_test_mulrev');
39 * Test getLoadedRevisionId() returns the correct ID throughout the process.
41 public function testLoadedRevisionId() {
42 // Create a basic EntityTestMulRev entity and save it.
43 $entity = EntityTestMulRev::create();
46 // Load the created entity and create a new revision.
47 $loaded = EntityTestMulRev::load($entity->id());
48 $loaded->setNewRevision(TRUE);
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
53 $this->assertEquals($entity->getRevisionId(), $loaded->getLoadedRevisionId());
54 $this->assertNotEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
55 $this->assertSame(NULL, $loaded->getRevisionId());
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());
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);
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());
81 * Tests the loaded revision ID after an entity re-save, clone and duplicate.
83 public function testLoadedRevisionIdWithNoNewRevision() {
84 // Create a basic EntityTestMulRev entity and save it.
85 $entity = EntityTestMulRev::create();
88 // Load the created entity and create a new revision.
89 $loaded = EntityTestMulRev::load($entity->id());
90 $loaded->setNewRevision(TRUE);
93 // Make a change to the loaded entity.
94 $loaded->set('name', 'dublin');
96 // The revision id and loaded Revision id should still be the same.
97 $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
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
105 $loadedRevisionId = \Drupal::state()->get('entity_test.loadedRevisionId');
106 $this->assertEquals($loaded->getRevisionId(), $loadedRevisionId);
107 $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId());
109 // Creating a clone should keep the loaded Revision ID.
110 $clone = clone $loaded;
111 $this->assertSame($loaded->getLoadedRevisionId(), $clone->getLoadedRevisionId());
113 // Creating a duplicate should set a NULL loaded Revision ID.
114 $duplicate = $loaded->createDuplicate();
115 $this->assertSame(NULL, $duplicate->getLoadedRevisionId());
119 * Tests the loaded revision ID for translatable entities.
121 public function testTranslatedLoadedRevisionId() {
122 ConfigurableLanguage::createFromLangcode('fr')->save();
124 // Create a basic EntityTestMulRev entity and save it.
125 $entity = EntityTestMulRev::create();
128 // Load the created entity and create a new revision.
129 $loaded = EntityTestMulRev::load($entity->id());
130 $loaded->setNewRevision(TRUE);
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());
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());
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());
160 * Tests re-saving the entity in entity_test_entity_insert().
162 public function testSaveInHookEntityInsert() {
163 // Create an entity which will be saved again in entity_test_entity_insert().
164 $entity = EntityTestMulRev::create(['name' => 'EntityLoadedRevisionTest']);
166 $loadedRevisionId = \Drupal::state()->get('entity_test.loadedRevisionId');
167 $this->assertEquals($entity->getLoadedRevisionId(), $loadedRevisionId);
168 $this->assertEquals($entity->getRevisionId(), $entity->getLoadedRevisionId());
172 * Tests that latest revisions are working as expected.
174 * @covers ::isLatestRevision
176 public function testIsLatestRevision() {
177 // Create a basic EntityTestMulRev entity and save it.
178 $entity = EntityTestMulRev::create();
180 $this->assertTrue($entity->isLatestRevision());
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);
187 // The pending revision should still be marked as the latest one before it
189 $this->assertTrue($pending_revision->isLatestRevision());
190 $pending_revision->save();
191 $this->assertTrue($pending_revision->isLatestRevision());
193 // Load the default revision and check that it is not marked as the latest
195 $default_revision = EntityTestMulRev::load($entity->id());
196 $this->assertFalse($default_revision->isLatestRevision());
200 * Tests that latest affected revisions are working as expected.
202 * The latest revision affecting a particular translation behaves as the
203 * latest revision for monolingual entities.
205 * @covers ::isLatestTranslationAffectedRevision
206 * @covers \Drupal\Core\Entity\ContentEntityStorageBase::getLatestRevisionId
207 * @covers \Drupal\Core\Entity\ContentEntityStorageBase::getLatestTranslationAffectedRevisionId
209 public function testIsLatestAffectedRevisionTranslation() {
210 ConfigurableLanguage::createFromLangcode('it')->save();
212 // Create a basic EntityTestMulRev entity and save it.
213 $entity = EntityTestMulRev::create();
214 $entity->setName($this->randomString());
216 $this->assertTrue($entity->isLatestTranslationAffectedRevision());
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);
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()));
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());
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());
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());