From 07181537554088661a57b197352ff239d7ffe6b3 Mon Sep 17 00:00:00 2001
From: webchick <drupal@webchick.net>
Date: Thu, 12 Nov 2015 14:30:00 -0800
Subject: [PATCH] Issue #2603010 by neclimdul, webflo, mikeryan: EntityRevision
 destination can explode with missing nodes

---
 .../migrate/destination/EntityContentBase.php |   3 +
 .../destination/EntityContentBaseTest.php     | 118 ++++++++++++++++++
 2 files changed, 121 insertions(+)
 create mode 100644 core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php

diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php
index 4dfd6c6e0ab3..ff7b2582af76 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php
@@ -90,6 +90,9 @@ public static function create(ContainerInterface $container, array $configuratio
   public function import(Row $row, array $old_destination_id_values = array()) {
     $this->rollbackAction = MigrateIdMapInterface::ROLLBACK_DELETE;
     $entity = $this->getEntity($row, $old_destination_id_values);
+    if (!$entity) {
+      throw new MigrateException('Unable to get entity');
+    }
     return $this->save($entity, $old_destination_id_values);
   }
 
diff --git a/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php b/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php
new file mode 100644
index 000000000000..220cbe84e1c1
--- /dev/null
+++ b/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\migrate\Unit\Plugin\migrate\destination\EntityContentBaseTest
+ */
+
+namespace Drupal\Tests\migrate\Unit\Plugin\migrate\destination;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
+use Drupal\migrate\Entity\MigrationInterface;
+use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
+use Drupal\migrate\Plugin\MigrateIdMapInterface;
+use Drupal\migrate\Row;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests base entity migration destination functionality.
+ *
+ * @coversDefaultClass \Drupal\migrate\Plugin\migrate\destination\EntityContentBase
+ * @group migrate
+ */
+class EntityContentBaseTest extends UnitTestCase {
+
+  /**
+   * @var \Drupal\migrate\Entity\MigrationInterface
+   */
+  protected $migration;
+
+  /**
+   * @var \Drupal\Core\Entity\EntityStorageInterface
+   */
+  protected $storage;
+
+  /**
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->migration = $this->prophesize(MigrationInterface::class);
+    $this->storage = $this->prophesize(EntityStorageInterface::class);
+    $this->entityManager = $this->prophesize(EntityManagerInterface::class);
+  }
+
+  /**
+   * Test basic entity save.
+   *
+   * @covers ::import
+   */
+  public function testImport() {
+    $bundles = [];
+    $destination = new EntityTestDestination([], '', [],
+      $this->migration->reveal(),
+      $this->storage->reveal(),
+      $bundles,
+      $this->entityManager->reveal(),
+      $this->prophesize(FieldTypePluginManagerInterface::class)->reveal());
+    $entity = $this->prophesize(ContentEntityInterface::class);
+    // Assert that save is called.
+    $entity->save()
+      ->shouldBeCalledTimes(1);
+    // Set an id for the entity
+    $entity->id()
+      ->willReturn(5);
+    $destination->setEntity($entity->reveal());
+    // Ensure the id is saved entity id is returned from import.
+    $this->assertEquals([5], $destination->import(new Row([], [])));
+    // Assert that import set the rollback action.
+    $this->assertEquals(MigrateIdMapInterface::ROLLBACK_DELETE, $destination->rollbackAction());
+  }
+
+  /**
+   * Test row skipping when we can't get an entity to save.
+   *
+   * @covers ::import
+   * @expectedException \Drupal\migrate\MigrateException
+   * @expectedExceptionMessage Unable to get entity
+   */
+  public function testImportEntityLoadFailure() {
+    $bundles = [];
+    $destination = new EntityTestDestination([], '', [],
+      $this->migration->reveal(),
+      $this->storage->reveal(),
+      $bundles,
+      $this->entityManager->reveal(),
+      $this->prophesize(FieldTypePluginManagerInterface::class)->reveal());
+    $destination->setEntity(FALSE);
+    $destination->import(new Row([], []));
+  }
+
+}
+
+/**
+ * Stub class for testing EntityContentBase methods.
+ *
+ * We want to test things without testing the base class implementations.
+ */
+class EntityTestDestination extends EntityContentBase {
+
+  private $entity = NULL;
+
+  public function setEntity($entity) {
+    $this->entity = $entity;
+  }
+
+  protected function getEntity(Row $row, array $old_destination_id_values) {
+    return $this->entity;
+  }
+}
-- 
GitLab