3 namespace Drupal\Tests\Core\Entity;
5 use Drupal\Core\Entity\EntityForm;
6 use Drupal\Core\Entity\EntityInterface;
7 use Drupal\Core\Entity\EntityStorageInterface;
8 use Drupal\Core\Entity\EntityType;
9 use Drupal\Core\Entity\EntityTypeManagerInterface;
10 use Drupal\Core\Form\FormState;
11 use Drupal\Core\Routing\RouteMatch;
12 use Drupal\Tests\UnitTestCase;
13 use Symfony\Component\Routing\Route;
16 * @coversDefaultClass \Drupal\Core\Entity\EntityForm
19 class EntityFormTest extends UnitTestCase {
22 * The mocked entity form.
24 * @var \Drupal\Core\Entity\EntityFormInterface|\PHPUnit_Framework_MockObject_MockObject
26 protected $entityForm;
29 * A fake entity type used in the test.
31 * @var \Drupal\Core\Entity\EntityTypeInterface
33 protected $entityType;
38 protected function setUp() {
41 $this->entityForm = new EntityForm();
42 $this->entityType = new EntityType(['id' => 'entity_test']);
46 * Tests the form ID generation.
50 * @dataProvider providerTestFormIds
52 public function testFormId($expected, $definition) {
53 $this->entityType->set('entity_keys', ['bundle' => $definition['bundle']]);
55 $entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', [[], $definition['entity_type']], '', TRUE, TRUE, TRUE, ['getEntityType', 'bundle']);
57 $entity->expects($this->any())
58 ->method('getEntityType')
59 ->will($this->returnValue($this->entityType));
60 $entity->expects($this->any())
62 ->will($this->returnValue($definition['bundle']));
64 $this->entityForm->setEntity($entity);
65 $this->entityForm->setOperation($definition['operation']);
67 $this->assertSame($expected, $this->entityForm->getFormId());
71 * Provides test data for testFormId().
73 public function providerTestFormIds() {
75 ['node_article_form', [
76 'entity_type' => 'node',
77 'bundle' => 'article',
78 'operation' => 'default',
80 ['node_article_delete_form', [
81 'entity_type' => 'node',
82 'bundle' => 'article',
83 'operation' => 'delete',
86 'entity_type' => 'user',
88 'operation' => 'default',
91 'entity_type' => 'user',
93 'operation' => 'default',
95 ['user_delete_form', [
96 'entity_type' => 'user',
98 'operation' => 'delete',
104 * @covers ::copyFormValuesToEntity
106 public function testCopyFormValuesToEntity() {
107 $entity_id = 'test_config_entity_id';
108 $values = ['id' => $entity_id];
109 $entity = $this->getMockBuilder('\Drupal\Tests\Core\Config\Entity\Fixtures\ConfigEntityBaseWithPluginCollections')
110 ->setConstructorArgs([$values, 'test_config_entity'])
111 ->setMethods(['getPluginCollections'])
113 $entity->expects($this->atLeastOnce())
114 ->method('getPluginCollections')
115 ->willReturn(['key_controlled_by_plugin_collection' => NULL]);
116 $this->entityForm->setEntity($entity);
118 $form_state = (new FormState())->setValues([
119 'regular_key' => 'foo',
120 'key_controlled_by_plugin_collection' => 'bar',
122 $result = $this->entityForm->buildEntity([], $form_state);
124 $this->assertSame($entity_id, $result->id());
125 // The regular key should have a value, but the one controlled by a plugin
126 // collection should not have been set.
127 $this->assertSame('foo', $result->get('regular_key'));
128 $this->assertNull($result->get('key_controlled_by_plugin_collection'));
132 * Tests EntityForm::getEntityFromRouteMatch() for edit and delete forms.
134 * @covers ::getEntityFromRouteMatch
136 public function testGetEntityFromRouteMatchEditDelete() {
137 $entity = $this->prophesize(EntityInterface::class)->reveal();
138 $id = $this->entityType->id();
139 $route_match = new RouteMatch(
141 new Route('/entity-test/manage/{' . $id . '}/edit'),
145 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $id);
146 $this->assertEquals($entity, $actual);
150 * Tests EntityForm::getEntityFromRouteMatch() for add forms without a bundle.
152 * @covers ::getEntityFromRouteMatch
154 public function testGetEntityFromRouteMatchAdd() {
155 $entity = $this->prophesize(EntityInterface::class)->reveal();
156 $this->setUpStorage()->create([])->willReturn($entity);
157 $route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
158 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
159 $this->assertEquals($entity, $actual);
163 * Tests EntityForm::getEntityFromRouteMatch() with a static bundle.
165 * @covers ::getEntityFromRouteMatch
167 public function testGetEntityFromRouteMatchAddStatic() {
168 $entity = $this->prophesize(EntityInterface::class)->reveal();
169 $bundle_key = 'bundle';
170 $bundle = 'test_bundle';
171 $this->entityType->set('entity_keys', ['bundle' => $bundle_key]);
172 $storage = $this->setUpStorage();
174 // Test without a bundle parameter in the route.
175 $storage->create([])->willReturn($entity);
176 $route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
177 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
178 $this->assertEquals($entity, $actual);
180 // Test with a static bundle parameter.
181 $storage->create([$bundle_key => 'test_bundle'])->willReturn($entity);
182 $route_match = new RouteMatch(
184 new Route('/entity-test/add/{' . $bundle_key . '}'),
185 [$bundle_key => $bundle],
186 [$bundle_key => $bundle]
188 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
189 $this->assertEquals($entity, $actual);
193 * Tests EntityForm::getEntityFromRouteMatch() with a config entity bundle.
195 * @covers ::getEntityFromRouteMatch
197 public function testGetEntityFromRouteMatchAddEntity() {
198 $entity = $this->prophesize(EntityInterface::class)->reveal();
199 $bundle_entity_type_id = 'entity_test_bundle';
200 $bundle = 'test_entity_bundle';
201 $this->entityType->set('bundle_entity_type', $bundle_entity_type_id);
202 $storage = $this->setUpStorage();
204 // Test without a bundle parameter in the route.
205 $storage->create([])->willReturn($entity);
206 $route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
207 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
208 $this->assertEquals($entity, $actual);
210 // Test with an entity bundle parameter.
211 $storage->create(['bundle' => $bundle])->willReturn($entity);
212 $bundle_entity = $this->prophesize(EntityInterface::class);
213 $bundle_entity->id()->willReturn('test_entity_bundle');
214 $route_match = new RouteMatch(
216 new Route('/entity-test/add/{entity_test_bundle}'),
217 [$bundle_entity_type_id => $bundle_entity->reveal()],
218 [$bundle_entity_type_id => $bundle]
220 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
221 $this->assertEquals($entity, $actual);
225 * Sets up the storage accessed via the entity type manager in the form.
227 * @return \Prophecy\Prophecy\ObjectProphecy
228 * The storage prophecy.
230 protected function setUpStorage() {
231 $storage = $this->prophesize(EntityStorageInterface::class);
233 $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
234 $entity_type_manager->getDefinition($this->entityType->id())->willReturn($this->entityType);
235 $entity_type_manager->getStorage($this->entityType->id())->willReturn($storage->reveal());
237 $this->entityForm->setEntityTypeManager($entity_type_manager->reveal());