You are here

public function EntityReferenceRevisionsCompositeTranslatableFieldTest::testCompositePendingRevisionTranslation in Entity Reference Revisions 8

Test the storage for handling pending revisions with translations.

File

tests/src/Kernel/EntityReferenceRevisionsCompositeTranslatableFieldTest.php, line 104

Class

EntityReferenceRevisionsCompositeTranslatableFieldTest
Tests entity_reference_revisions composites with a translatable field.

Namespace

Drupal\Tests\entity_reference_revisions\Kernel

Code

public function testCompositePendingRevisionTranslation() {

  /** @var \Drupal\node\NodeStorageInterface $node_storage */
  $node_storage = \Drupal::entityTypeManager()
    ->getStorage('node');

  // Create the test composite entity.
  $composite = EntityTestCompositeRelationship::create([
    'langcode' => 'en',
    'name' => 'Initial Source Composite',
  ]);
  $composite
    ->save();

  // Create a node with a reference to the test composite entity.
  $node = Node::create([
    'langcode' => 'en',
    'title' => 'Initial Source Node',
    'type' => 'article',
    'composite_reference' => $composite,
  ]);
  $node
    ->save();

  /** @var \Drupal\node\NodeInterface $node */
  $node = $node_storage
    ->load($node
    ->id());

  // Assert the revision count.
  $this
    ->assertRevisionCount(1, 'node', $node
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite
    ->id());

  // Create a translation as a pending revision for both the composite and the
  // node. While technically, the referenced composite could be the same
  // entity, for translatable fields, it makes more sense if each translation
  // points to a separate entity, each only with a single language.
  $composite_de = $node
    ->get('composite_reference')->entity
    ->createDuplicate();
  $composite_de
    ->set('langcode', 'de');
  $composite_de
    ->set('name', 'Pending Revision Composite #1 DE');

  /** @var \Drupal\node\NodeInterface $node_de */
  $node_de = $node
    ->addTranslation('de', [
    'title' => 'Pending Revision Node #1 DE',
    'composite_reference' => $composite_de,
  ] + $node
    ->toArray());
  $node_de
    ->setNewRevision(TRUE);
  $node_de
    ->isDefaultRevision(FALSE);
  $node_de
    ->save();

  // Assert the revision count.
  $this
    ->assertRevisionCount(2, 'node', $node
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_de
    ->id());

  // The DE translation will now reference to a pending revision of the
  // composite entity but the en translation will reference the existing,
  // unchanged revision.

  /** @var \Drupal\node\NodeInterface $node_revision */
  $node_revision = $node_storage
    ->loadRevision($node_de
    ->getRevisionId());
  $this
    ->assertFalse($node_revision
    ->isDefaultRevision());
  $this
    ->assertFalse((bool) $node_revision
    ->isRevisionTranslationAffected());
  $this
    ->assertEquals('Initial Source Node', $node_revision
    ->label());
  $this
    ->assertTrue($node_revision
    ->get('composite_reference')->entity
    ->isDefaultRevision());
  $this
    ->assertEquals('Initial Source Composite', $node_revision
    ->get('composite_reference')->entity
    ->label());
  $this
    ->assertFalse($node_revision
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertEquals($node
    ->get('composite_reference')->target_revision_id, $node_revision
    ->get('composite_reference')->target_revision_id);
  $node_de = $node_revision
    ->getTranslation('de');
  $this
    ->assertTrue((bool) $node_de
    ->isRevisionTranslationAffected());
  $this
    ->assertEquals('Pending Revision Node #1 DE', $node_de
    ->label());

  // The composite is the default revision because it is a new entity.
  $this
    ->assertTrue($node_de
    ->get('composite_reference')->entity
    ->isDefaultRevision());
  $this
    ->assertEquals('Pending Revision Composite #1 DE', $node_de
    ->get('composite_reference')->entity
    ->label());
  $this
    ->assertNotEquals($node
    ->get('composite_reference')->target_revision_id, $node_de
    ->get('composite_reference')->target_revision_id);

  // Reload the default revision of the node, make sure that the composite
  // there is unchanged.
  $node = $node_storage
    ->load($node
    ->id());
  $this
    ->assertFalse($node
    ->hasTranslation('de'));
  $this
    ->assertEquals('Initial Source Node', $node
    ->label());
  $this
    ->assertFalse($node
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertEquals('Initial Source Composite', $node
    ->get('composite_reference')->entity
    ->label());

  // Create a second translation revision for FR.
  $composite_fr = $node
    ->get('composite_reference')->entity
    ->createDuplicate();
  $composite_fr
    ->set('langcode', 'fr');
  $composite_fr
    ->set('name', 'Pending Revision Composite #1 FR');
  $node_fr = $node
    ->addTranslation('fr', [
    'title' => 'Pending Revision Node #1 FR',
    'composite_reference' => $composite_fr,
  ] + $node
    ->toArray());
  $node_fr
    ->setNewRevision(TRUE);
  $node_fr
    ->isDefaultRevision(FALSE);
  $node_fr
    ->save();

  // Assert the revision count.
  $this
    ->assertRevisionCount(3, 'node', $node
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_de
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_fr
    ->id());

  // Now assert that all 3 revisions exist as expected. Two translation
  // pending revisions, each has the original revision as parent without
  // any existing translation.

  /** @var \Drupal\node\NodeInterface $node_fr */
  $node_revision = $node_storage
    ->loadRevision($node_fr
    ->getRevisionId());
  $this
    ->assertFalse($node_revision
    ->isDefaultRevision());
  $this
    ->assertFalse((bool) $node_revision
    ->isRevisionTranslationAffected());
  $this
    ->assertEquals('Initial Source Node', $node_revision
    ->label());
  $this
    ->assertTrue($node_revision
    ->get('composite_reference')->entity
    ->isDefaultRevision());
  $this
    ->assertEquals('Initial Source Composite', $node_revision
    ->get('composite_reference')->entity
    ->label());
  $this
    ->assertFalse($node_revision
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertEquals($node
    ->get('composite_reference')->target_revision_id, $node_revision
    ->get('composite_reference')->target_revision_id);
  $node_fr = $node_revision
    ->getTranslation('fr');
  $this
    ->assertTrue((bool) $node_fr
    ->isRevisionTranslationAffected());
  $this
    ->assertEquals('Pending Revision Node #1 FR', $node_fr
    ->label());
  $this
    ->assertTrue($node_fr
    ->get('composite_reference')->entity
    ->isDefaultRevision());
  $this
    ->assertEquals('Pending Revision Composite #1 FR', $node_fr
    ->get('composite_reference')->entity
    ->label());
  $this
    ->assertNotEquals($node
    ->get('composite_reference')->target_revision_id, $node_fr
    ->get('composite_reference')->target_revision_id);
  $node_de = $node_storage
    ->loadRevision($node_de
    ->getRevisionId())
    ->getTranslation('de');
  $this
    ->assertTrue((bool) $node_de
    ->isRevisionTranslationAffected());
  $this
    ->assertEquals('Pending Revision Node #1 DE', $node_de
    ->label());
  $this
    ->assertTrue($node_de
    ->get('composite_reference')->entity
    ->isDefaultRevision());
  $this
    ->assertEquals('Pending Revision Composite #1 DE', $node_de
    ->get('composite_reference')->entity
    ->label());
  $this
    ->assertNotEquals($node
    ->get('composite_reference')->target_revision_id, $node_de
    ->get('composite_reference')->target_revision_id);

  // Reload the default revision of the node, make sure that the composite
  // there is unchanged.
  $node = $node_storage
    ->load($node
    ->id());
  $this
    ->assertFalse($node
    ->hasTranslation('de'));
  $this
    ->assertEquals('Initial Source Node', $node
    ->label());
  $this
    ->assertFalse($node
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertEquals('Initial Source Composite', $node
    ->get('composite_reference')->entity
    ->label());

  // Now make a change to the initial source revision, save as a new default
  // revision.
  $initial_revision_id = $node
    ->getRevisionId();
  $node
    ->get('composite_reference')->entity
    ->set('name', 'Updated Source Composite');
  $node
    ->setTitle('Updated Source Node');
  $node
    ->setNewRevision(TRUE);
  $node
    ->save();

  // Assert the revision count.
  $this
    ->assertRevisionCount(4, 'node', $node
    ->id());
  $this
    ->assertRevisionCount(2, 'entity_test_composite', $composite
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_de
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_fr
    ->id());

  // Assert the two english revisions.
  // Reload the default revision of the node, make sure that the composite
  // there is unchanged.
  $node = $node_storage
    ->load($node
    ->id());
  $this
    ->assertTrue($node
    ->isDefaultRevision());
  $this
    ->assertFalse($node
    ->hasTranslation('de'));
  $this
    ->assertFalse($node
    ->hasTranslation('fr'));
  $this
    ->assertTrue((bool) $node
    ->isRevisionTranslationAffected());
  $this
    ->assertEquals('Updated Source Node', $node
    ->label());
  $this
    ->assertTrue($node
    ->get('composite_reference')->entity
    ->isDefaultRevision());
  $this
    ->assertFalse($node
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertEquals('Updated Source Composite', $node
    ->get('composite_reference')->entity
    ->label());
  $node_initial = $node_storage
    ->loadRevision($initial_revision_id);
  $this
    ->assertFalse($node_initial
    ->isDefaultRevision());
  $this
    ->assertFalse($node_initial
    ->hasTranslation('de'));
  $this
    ->assertFalse($node_initial
    ->hasTranslation('fr'));
  $this
    ->assertEquals('Initial Source Node', $node_initial
    ->label());
  $this
    ->assertFalse($node_initial
    ->get('composite_reference')->entity
    ->isDefaultRevision());
  $this
    ->assertFalse($node_initial
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertEquals('Initial Source Composite', $node_initial
    ->get('composite_reference')->entity
    ->label());

  // Now publish the FR pending revision.
  $node_storage
    ->createRevision($node_fr
    ->getTranslation('fr'))
    ->save();

  // Assert the revision count.
  $this
    ->assertRevisionCount(5, 'node', $node
    ->id());
  $this
    ->assertRevisionCount(2, 'entity_test_composite', $composite
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_de
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_fr
    ->id());

  // The new default revision should now have the updated english source and
  // the french pending revision.
  $node = $node_storage
    ->load($node
    ->id());
  $this
    ->assertTrue($node
    ->isDefaultRevision());
  $this
    ->assertFalse($node
    ->hasTranslation('de'));
  $this
    ->assertTrue($node
    ->hasTranslation('fr'));
  $node_fr = $node
    ->getTranslation('fr');
  $this
    ->assertFalse((bool) $node
    ->isRevisionTranslationAffected());
  $this
    ->assertTrue((bool) $node
    ->getTranslation('fr')
    ->isRevisionTranslationAffected());
  $this
    ->assertEquals('Updated Source Node', $node
    ->label());
  $this
    ->assertTrue($node
    ->get('composite_reference')->entity
    ->isDefaultRevision());
  $this
    ->assertFalse($node
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertTrue($node_fr
    ->get('composite_reference')->entity
    ->hasTranslation('fr'));
  $this
    ->assertEquals('Pending Revision Node #1 FR', $node_fr
    ->label());
  $this
    ->assertEquals('Pending Revision Composite #1 FR', $node_fr
    ->get('composite_reference')->entity
    ->getTranslation('fr')
    ->label());
  $this
    ->assertEquals('Updated Source Composite', $node
    ->get('composite_reference')->entity
    ->label());

  // Now publish the DE pending revision as well.
  $node_storage
    ->createRevision($node_de
    ->getTranslation('de'))
    ->save();

  // Assert the revision count.
  $this
    ->assertRevisionCount(6, 'node', $node
    ->id());
  $this
    ->assertRevisionCount(2, 'entity_test_composite', $composite
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_de
    ->id());
  $this
    ->assertRevisionCount(1, 'entity_test_composite', $composite_fr
    ->id());

  // The new default revision should now have the updated source and both
  // translations.
  $node = $node_storage
    ->load($node
    ->id());
  $this
    ->assertTrue($node
    ->isDefaultRevision());
  $this
    ->assertTrue($node
    ->hasTranslation('de'));
  $this
    ->assertTrue($node
    ->hasTranslation('fr'));
  $node_fr = $node
    ->getTranslation('fr');
  $node_de = $node
    ->getTranslation('de');
  $this
    ->assertFalse((bool) $node
    ->isRevisionTranslationAffected());
  $this
    ->assertFalse((bool) $node
    ->getTranslation('fr')
    ->isRevisionTranslationAffected());
  $this
    ->assertTrue((bool) $node
    ->getTranslation('de')
    ->isRevisionTranslationAffected());
  $this
    ->assertEquals('Updated Source Node', $node
    ->label());

  // Each translation only has the composite in its translation.
  $this
    ->assertTrue($node
    ->get('composite_reference')->entity
    ->hasTranslation('en'));
  $this
    ->assertFalse($node
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertFalse($node
    ->get('composite_reference')->entity
    ->hasTranslation('fr'));
  $this
    ->assertFalse($node_fr
    ->get('composite_reference')->entity
    ->hasTranslation('en'));
  $this
    ->assertTrue($node_fr
    ->get('composite_reference')->entity
    ->hasTranslation('fr'));
  $this
    ->assertFalse($node_fr
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertFalse($node_de
    ->get('composite_reference')->entity
    ->hasTranslation('en'));
  $this
    ->assertTrue($node_de
    ->get('composite_reference')->entity
    ->hasTranslation('de'));
  $this
    ->assertFalse($node_de
    ->get('composite_reference')->entity
    ->hasTranslation('fr'));
  $this
    ->assertEquals('Pending Revision Node #1 FR', $node_fr
    ->label());
  $this
    ->assertEquals('Pending Revision Composite #1 FR', $node_fr
    ->get('composite_reference')->entity
    ->getTranslation('fr')
    ->label());
  $this
    ->assertEquals('Pending Revision Node #1 DE', $node_de
    ->label());
  $this
    ->assertEquals('Pending Revision Composite #1 DE', $node_de
    ->get('composite_reference')->entity
    ->getTranslation('de')
    ->label());
  $this
    ->assertEquals('Updated Source Composite', $node
    ->get('composite_reference')->entity
    ->label());
}