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',
81 ['node_article_delete_form', [
82 'entity_type' => 'node',
83 'bundle' => 'article',
84 'operation' => 'delete',
88 'entity_type' => 'user',
90 'operation' => 'default',
94 'entity_type' => 'user',
96 'operation' => 'default',
99 ['user_delete_form', [
100 'entity_type' => 'user',
102 'operation' => 'delete',
109 * @covers ::copyFormValuesToEntity
111 public function testCopyFormValuesToEntity() {
112 $entity_id = 'test_config_entity_id';
113 $values = ['id' => $entity_id];
114 $entity = $this->getMockBuilder('\Drupal\Tests\Core\Config\Entity\Fixtures\ConfigEntityBaseWithPluginCollections')
115 ->setConstructorArgs([$values, 'test_config_entity'])
116 ->setMethods(['getPluginCollections'])
118 $entity->expects($this->atLeastOnce())
119 ->method('getPluginCollections')
120 ->willReturn(['key_controlled_by_plugin_collection' => NULL]);
121 $this->entityForm->setEntity($entity);
123 $form_state = (new FormState())->setValues([
124 'regular_key' => 'foo',
125 'key_controlled_by_plugin_collection' => 'bar',
127 $result = $this->entityForm->buildEntity([], $form_state);
129 $this->assertSame($entity_id, $result->id());
130 // The regular key should have a value, but the one controlled by a plugin
131 // collection should not have been set.
132 $this->assertSame('foo', $result->get('regular_key'));
133 $this->assertNull($result->get('key_controlled_by_plugin_collection'));
137 * Tests EntityForm::getEntityFromRouteMatch() for edit and delete forms.
139 * @covers ::getEntityFromRouteMatch
141 public function testGetEntityFromRouteMatchEditDelete() {
142 $entity = $this->prophesize(EntityInterface::class)->reveal();
143 $id = $this->entityType->id();
144 $route_match = new RouteMatch(
146 new Route('/entity-test/manage/{' . $id . '}/edit'),
150 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $id);
151 $this->assertEquals($entity, $actual);
155 * Tests EntityForm::getEntityFromRouteMatch() for add forms without a bundle.
157 * @covers ::getEntityFromRouteMatch
159 public function testGetEntityFromRouteMatchAdd() {
160 $entity = $this->prophesize(EntityInterface::class)->reveal();
161 $this->setUpStorage()->create([])->willReturn($entity);
162 $route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
163 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
164 $this->assertEquals($entity, $actual);
168 * Tests EntityForm::getEntityFromRouteMatch() with a static bundle.
170 * @covers ::getEntityFromRouteMatch
172 public function testGetEntityFromRouteMatchAddStatic() {
173 $entity = $this->prophesize(EntityInterface::class)->reveal();
174 $bundle_key = 'bundle';
175 $bundle = 'test_bundle';
176 $this->entityType->set('entity_keys', ['bundle' => $bundle_key]);
177 $storage = $this->setUpStorage();
179 // Test without a bundle parameter in the route.
180 $storage->create([])->willReturn($entity);
181 $route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
182 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
183 $this->assertEquals($entity, $actual);
185 // Test with a static bundle parameter.
186 $storage->create([$bundle_key => 'test_bundle'])->willReturn($entity);
187 $route_match = new RouteMatch(
189 new Route('/entity-test/add/{' . $bundle_key . '}'),
190 [$bundle_key => $bundle],
191 [$bundle_key => $bundle]
193 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
194 $this->assertEquals($entity, $actual);
198 * Tests EntityForm::getEntityFromRouteMatch() with a config entity bundle.
200 * @covers ::getEntityFromRouteMatch
202 public function testGetEntityFromRouteMatchAddEntity() {
203 $entity = $this->prophesize(EntityInterface::class)->reveal();
204 $bundle_entity_type_id = 'entity_test_bundle';
205 $bundle = 'test_entity_bundle';
206 $this->entityType->set('bundle_entity_type', $bundle_entity_type_id);
207 $storage = $this->setUpStorage();
209 // Test without a bundle parameter in the route.
210 $storage->create([])->willReturn($entity);
211 $route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
212 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
213 $this->assertEquals($entity, $actual);
215 // Test with an entity bundle parameter.
216 $storage->create(['bundle' => $bundle])->willReturn($entity);
217 $bundle_entity = $this->prophesize(EntityInterface::class);
218 $bundle_entity->id()->willReturn('test_entity_bundle');
219 $route_match = new RouteMatch(
221 new Route('/entity-test/add/{entity_test_bundle}'),
222 [$bundle_entity_type_id => $bundle_entity->reveal()],
223 [$bundle_entity_type_id => $bundle]
225 $actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
226 $this->assertEquals($entity, $actual);
230 * Sets up the storage accessed via the entity type manager in the form.
232 * @return \Prophecy\Prophecy\ObjectProphecy
233 * The storage prophecy.
235 protected function setUpStorage() {
236 $storage = $this->prophesize(EntityStorageInterface::class);
238 $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
239 $entity_type_manager->getDefinition($this->entityType->id())->willReturn($this->entityType);
240 $entity_type_manager->getStorage($this->entityType->id())->willReturn($storage->reveal());
242 $this->entityForm->setEntityTypeManager($entity_type_manager->reveal());