Commit a2c96ec5 authored by alexpott's avatar alexpott

Issue #2578955 by dawehner, jhodgdon, Wim Leers, catch: Implement auto route...

Issue #2578955 by dawehner, jhodgdon, Wim Leers, catch: Implement auto route generation but DON'T use it for all core entities
parent cea9c14b
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Controller\EntityController.
*/
namespace Drupal\Core\Entity\Controller;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides generic entity title callbacks for use in routing.
*
* It provides:
* - A view title callback.
* - An edit title callback.
* - A delete title callback.
*/
class EntityController implements ContainerInjectionInterface {
use StringTranslationTrait;
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityManagerInterface
*/
protected $entityManager;
/**
* Constructs a new EntityController.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The string translation.
*/
public function __construct(EntityManagerInterface $entity_manager, TranslationInterface $string_translation) {
$this->entityManager = $entity_manager;
$this->stringTranslation = $string_translation;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
$container->get('string_translation')
);
}
/**
* Provides a generic title callback for a single entity.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match.
* @param \Drupal\Core\Entity\EntityInterface $_entity
* (optional) An entity, passed in directly from the request attributes.
*
* @return string
* The title for the entity view page.
*/
public function title(RouteMatchInterface $route_match, EntityInterface $_entity = NULL) {
if ($entity = $this->doGetEntity($route_match, $_entity)) {
return $entity->label();
}
}
/**
* Provides a generic edit title callback.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match.
* @param \Drupal\Core\Entity\EntityInterface $_entity
* (optional) An entity, passed in directly from the request attributes.
*
* @return string
* The title for the entity edit page.
*/
public function editTitle(RouteMatchInterface $route_match, EntityInterface $_entity = NULL) {
if ($entity = $this->doGetEntity($route_match, $_entity)) {
return $this->t('Edit %label', ['%label' => $entity->label()]);
}
}
/**
* Provides a generic delete title callback.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match.
* @param \Drupal\Core\Entity\EntityInterface $_entity
* (optional) An entity, passed in directly from the request attributes, and
* set in \Drupal\Core\Entity\Enhancer\EntityRouteEnhancer.
*
* @return string
* The title for the delete entity page.
*/
public function deleteTitle(RouteMatchInterface $route_match, EntityInterface $_entity = NULL) {
if ($entity = $this->doGetEntity($route_match, $_entity)) {
return $this->t('Delete %label', ['%label' => $entity->label()]);
}
}
/**
* Determines the entity.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match.
* @param \Drupal\Core\Entity\EntityInterface $_entity
* (optional) The entity, set in
* \Drupal\Core\Entity\Enhancer\EntityRouteEnhancer.
*
* @return \Drupal\Core\Entity\EntityInterface|NULL
* The entity, if it is passed in directly or if the first parameter of the
* active route is an entity; otherwise, NULL.
*/
protected function doGetEntity(RouteMatchInterface $route_match, EntityInterface $_entity = NULL) {
if ($_entity) {
$entity = $_entity;
}
else {
// Let's look up in the route object for the name of upcasted values.
foreach ($route_match->getParameters() as $parameter) {
if ($parameter instanceof EntityInterface) {
$entity = $parameter;
break;
}
}
}
if ($entity) {
return $this->entityManager->getTranslationFromContext($entity);
}
}
}
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider.
*/
namespace Drupal\Core\Entity\Routing;
use Drupal\Core\Entity\EntityTypeInterface;
/**
* Provides HTML routes for entities with administrative edit/delete pages.
*
* Use this class if the edit and delete form routes should use the
* administrative theme.
*
* @see \Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider.
*
* @internal
*/
class AdminHtmlRouteProvider extends DefaultHtmlRouteProvider {
/**
* {@inheritdoc}
*/
protected function getEditFormRoute(EntityTypeInterface $entity_type) {
if ($route = parent::getEditFormRoute($entity_type)) {
$route->setOption('_admin_route', TRUE);
return $route;
}
}
/**
* {@inheritdoc}
*/
protected function getDeleteFormRoute(EntityTypeInterface $entity_type) {
if ($route = parent::getDeleteFormRoute($entity_type)) {
$route->setOption('_admin_route', TRUE);
return $route;
}
}
}
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider.
*/
namespace Drupal\Core\Entity\Routing;
use Drupal\Core\Entity\EntityTypeInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* Provides HTML routes for entities.
*
* This class provides the following routes for entities, with title and access
* callbacks:
* - canonical
* - edit-form
* - delete-form
*
* @see \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider.
*
* @internal
*/
class DefaultHtmlRouteProvider implements EntityRouteProviderInterface {
/**
* {@inheritdoc}
*/
public function getRoutes(EntityTypeInterface $entity_type) {
$collection = new RouteCollection();
$entity_type_id = $entity_type->id();
if ($edit_route = $this->getEditFormRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.edit_form", $edit_route);
}
if ($canonical_route = $this->getCanonicalRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.canonical", $canonical_route);
}
if ($delete_route = $this->getDeleteFormRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.delete_form", $delete_route);
}
return $collection;
}
/**
* Gets the canonical route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getCanonicalRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('canonical') && $entity_type->hasViewBuilderClass()) {
$entity_type_id = $entity_type->id();
$route = new Route($entity_type->getLinkTemplate('canonical'));
$route
->addDefaults([
'_entity_view' => "{$entity_type_id}.full",
'_title_callback' => '\Drupal\Core\Entity\Controller\EntityController::title',
])
->setRequirement('_entity_access', "{$entity_type_id}.view")
->setOption('parameters', [
$entity_type_id => ['type' => 'entity:' . $entity_type_id],
]);
return $route;
}
}
/**
* Gets the edit-form route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getEditFormRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('edit-form')) {
$entity_type_id = $entity_type->id();
$route = new Route($entity_type->getLinkTemplate('edit-form'));
// Use the edit form handler, if available, otherwise default.
$operation = 'default';
if ($entity_type->getFormClass('edit')) {
$operation = 'edit';
}
$route
->setDefaults([
'_entity_form' => "{$entity_type_id}.{$operation}",
'_title_callback' => '\Drupal\Core\Entity\Controller\EntityController::editTitle'
])
->setRequirement('_entity_access', "{$entity_type_id}.update")
->setOption('parameters', [
$entity_type_id => ['type' => 'entity:' . $entity_type_id],
]);
return $route;
}
}
/**
* Gets the delete-form route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getDeleteFormRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('delete-form')) {
$entity_type_id = $entity_type->id();
$route = new Route($entity_type->getLinkTemplate('delete-form'));
$route
->addDefaults([
'_entity_form' => "{$entity_type_id}.delete",
'_title_callback' => '\Drupal\Core\Entity\Controller\EntityController::deleteTitle',
])
->setRequirement('_entity_access', "{$entity_type_id}.delete")
->setOption('parameters', [
$entity_type_id => ['type' => 'entity:' . $entity_type_id],
]);
return $route;
}
}
}
......@@ -324,7 +324,9 @@
* also need to add a corresponding route to your module's routing.yml file;
* see the entity.node.canonical route in node.routing.yml for an example, and see
* @ref sec_routes below for some notes.
* - Define routes and links for the various URLs associated with the entity.
* - Optionally, instead of defining routes, routes can be auto generated by
* providing a route handler. See @ref sec_routes. Otherwise, define routes
* and links for the various URLs associated with the entity.
* These go into the 'links' annotation, with the link type as the key, and
* the path of this link template as the value. The corresponding route
* requires the following route name:
......@@ -358,8 +360,10 @@
*
* @section sec_routes Entity routes
* Entity routes, like other routes, are defined in *.routing.yml files; see
* the @link menu Menu and routing @endlink topic for more information. Here
* is a typical entry, for the block configure form:
* the @link routing Routing API @endlink topic for more information. Entities
* may alternatively use an auto route provider class; there is an example of
* this at the end of this section. If providing routes directly, here is a
* typical entry, for the block configure form:
* @code
* entity.block.edit_form:
* path: '/admin/structure/block/manage/{block}'
......@@ -386,6 +390,19 @@
* "form" = {
* "default" = "Drupal\block\BlockForm",
* @endcode
* - Instead of putting the routes for your entity in a *.routing.yml file, you
* can instead use a route provider class.
* \Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider provides canonical,
* edit-form, and delete-form routes;
* \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider provides the same
* routes, set up to use the administrative theme for edit and delete pages.
* You can also create your own class. To use a route provider class, add
* lines like the following to your entity annotation:
* @code
* handlers = {
* "route_provider" = {
* "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
* @endcode
*
* @section bundle Defining a content entity bundle
* For entity types that use bundles, such as Node (bundles are content types)
......
......@@ -48,12 +48,14 @@ public function onDynamicRouteEvent(RouteBuildEvent $event) {
foreach ($this->entityManager->getRouteProviders($entity_type->id()) as $route_provider) {
// Allow to both return an array of routes or a route collection,
// like route_callbacks in the routing.yml file.
$routes = $route_provider->getRoutes($entity_type);
if ($routes instanceof RouteCollection) {
$route_collection->addCollection($routes);
$routes = $routes->all();
}
elseif (is_array($routes)) {
foreach ($routes as $route_name => $route) {
foreach ($routes as $route_name => $route) {
// Don't override existing routes.
if (!$route_collection->get($route_name)) {
$route_collection->add($route_name, $route);
}
}
......
......@@ -49,34 +49,6 @@ aggregator.feed_add:
options:
_admin_route: TRUE
entity.aggregator_feed.canonical:
path: '/aggregator/sources/{aggregator_feed}'
defaults:
_entity_view: 'aggregator_feed'
_title_callback: '\Drupal\aggregator\Controller\AggregatorController::feedTitle'
requirements:
_permission: 'access news feeds'
entity.aggregator_feed.edit_form:
path: '/aggregator/sources/{aggregator_feed}/configure'
defaults:
_entity_form: 'aggregator_feed.default'
_title: 'Configure'
requirements:
_permission: 'administer news feeds'
options:
_admin_route: TRUE
entity.aggregator_feed.delete_form:
path: '/aggregator/sources/{aggregator_feed}/delete'
defaults:
_entity_form: 'aggregator_feed.delete'
_title: 'Delete feed'
requirements:
_permission: 'administer news feeds'
options:
_admin_route: TRUE
aggregator.page_last:
path: '/aggregator'
defaults:
......
......@@ -29,7 +29,10 @@
* "default" = "Drupal\aggregator\FeedForm",
* "delete" = "Drupal\aggregator\Form\FeedDeleteForm",
* "delete_items" = "Drupal\aggregator\Form\FeedItemsDeleteForm",
* }
* },
* "route_provider" = {
* "html" = "Drupal\aggregator\FeedHtmlRouteProvider",
* },
* },
* links = {
* "canonical" = "/aggregator/sources/{aggregator_feed}",
......
<?php
/**
* @file
* Contains Drupal\aggregator\FeedHtmlRouteProvider.
*/
namespace Drupal\aggregator;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
/**
* Provides HTML routes for the feed entity type.
*/
class FeedHtmlRouteProvider extends AdminHtmlRouteProvider {
/**
* {@inheritdoc}
*/
protected function getCanonicalRoute(EntityTypeInterface $entity_type) {
$route = parent::getCanonicalRoute($entity_type);
$route->setDefault('_title_controller', '\Drupal\aggregator\Controller\AggregatorController::feedTitle');
return $route;
}
/**
* {@inheritdoc}
*/
protected function getEditFormRoute(EntityTypeInterface $entity_type) {
$route = parent::getEditFormRoute($entity_type);
$route->setDefault('_title', 'Configure');
return $route;
}
}
......@@ -61,8 +61,8 @@ public function testFeedLabelEscaping() {
$this->drupalGet('aggregator/sources/' . $feed->id());
$this->assertResponse(200);
$result = $this->xpath('//h1');
$this->assertEqual((string) $result[0], 'Test feed title alert(123);');
$this->assertEscaped('Test feed title <script>alert(123);</script>');
$this->assertNoRaw('Test feed title <script>alert(123);</script>');
// Ensure the feed icon title is escaped.
$this->assertTrue(strpos(str_replace(["\n", "\r"], '', $this->getRawContent()), 'class="feed-icon"> Subscribe to Test feed title &lt;script&gt;alert(123);&lt;/script&gt; feed</a>') !== FALSE);
......
......@@ -435,7 +435,7 @@ function testCommentFunctionality() {
$data = array('bundle' => 'entity_test', 'name' => $random_label);
$new_entity = entity_create('entity_test', $data);
$new_entity->save();
$this->drupalGet('entity_test/manage/' . $new_entity->id());
$this->drupalGet('entity_test/manage/' . $new_entity->id() . '/edit');
$this->assertNoFieldChecked('edit-field-foobar-0-status-1');
$this->assertFieldChecked('edit-field-foobar-0-status-2');
$this->assertNoField('edit-field-foobar-0-status-0');
......
......@@ -26,19 +26,6 @@ class ContentTestTranslationUITest extends ContentTranslationUITestBase {
*/
public static $modules = array('language', 'content_translation', 'entity_test');
/**
* {@inheritdoc}
*/
protected $defaultCacheContexts = [
'languages:language_interface',
'session',
'theme',
'url.path',
'url.query_args',
'user.permissions',
'user.roles:authenticated',
];
/**
* Overrides \Drupal\simpletest\WebTestBase::setUp().
*/
......
......@@ -87,7 +87,7 @@ public function testSupportedEntityTypesAndWidgets() {
// Try to post the form again with no modification and check if the field
// values remain the same.
$entity = current(entity_load_multiple_by_properties($this->entityType, array('name' => $entity_name)));
$this->drupalGet($this->entityType . '/manage/' . $entity->id());
$this->drupalGet($this->entityType . '/manage/' . $entity->id() . '/edit');
$this->assertFieldByName($this->fieldName . '[0][target_id]', $referenced_entities[0]->label() . ' (' . $referenced_entities[0]->id() . ')');
$this->assertFieldByName($this->fieldName . '[1][target_id]', $referenced_entities[1]->label() . ' (' . $referenced_entities[1]->id() . ')');
......@@ -113,7 +113,7 @@ public function testSupportedEntityTypesAndWidgets() {
// Try to post the form again with no modification and check if the field
// values remain the same.
$entity = current(entity_load_multiple_by_properties($this->entityType, array('name' => $entity_name)));
$this->drupalGet($this->entityType . '/manage/' . $entity->id());
$this->drupalGet($this->entityType . '/manage/' . $entity->id() . '/edit');
$this->assertFieldByName($this->fieldName . '[target_id]', $target_id . ' (' . $referenced_entities[1]->id() . ')');
$this->drupalPostForm(NULL, array(), t('Save'));
......@@ -132,7 +132,7 @@ public function testSupportedEntityTypesAndWidgets() {
'type' => $widget_type,
))->save();
$this->drupalPostForm($this->entityType . '/manage/' . $entity->id(), array(), t('Save'));
$this->drupalPostForm($this->entityType . '/manage/' . $entity->id() . '/edit', array(), t('Save'));
$this->assertFieldValues($entity_name, $referenced_entities);
}
......
......@@ -139,7 +139,7 @@ function testFieldFormSingle() {
$this->assertEqual($entity->{$field_name}->value, $value, 'Field value was saved');
// Display edit form.
$this->drupalGet('entity_test/manage/' . $id);
$this->drupalGet('entity_test/manage/' . $id . '/edit');
$this->assertFieldByName("{$field_name}[0][value]", $value, 'Widget is displayed with the correct default value');
$this->assertNoField("{$field_name}[1][value]", 'No extraneous widget is displayed');
......@@ -159,7 +159,7 @@ function testFieldFormSingle() {
$edit = array(
"{$field_name}[0][value]" => $value
);
$this->drupalPostForm('entity_test/manage/' . $id, $edit, t('Save'));
$this->drupalPostForm('entity_test/manage/' . $id . '/edit', $edit, t('Save'));
$this->assertText(t('entity_test @id has been updated.', array('@id' => $id)), 'Entity was updated');
$this->container->get('entity.manager')->getStorage('entity_test')->resetCache(array($id));
$entity = entity_load('entity_test', $id);
......@@ -231,7 +231,7 @@ function testFieldFormSingleRequired() {
$edit = array(
"{$field_name}[0][value]" => $value,
);
$this->drupalPostForm('entity_test/manage/' . $id, $edit, t('Save'));
$this->drupalPostForm('entity_test/manage/' . $id . '/edit', $edit, t('Save'));
$this->assertRaw(t('@name field is required.', array('@name' => $this->field['label'])), 'Required field with no value fails validation');
}
......@@ -491,7 +491,7 @@ function testFieldFormMultipleWidget() {
$this->assertFieldValues($entity_init, $field_name, array(1, 2, 3));
// Display the form, check that the values are correctly filled in.
$this->drupalGet('entity_test/manage/' . $id);
$this->drupalGet('entity_test/manage/' . $id . '/edit');
$this->assertFieldByName($field_name, '1, 2, 3', 'Widget is displayed.');
// Submit the form with more values than the field accepts.
......@@ -574,7 +574,7 @@ function testFieldFormAccess() {
"{$field_name}[0][value]" => 2,
'revision' => TRUE,
);
$this->drupalPostForm($entity_type . '/manage/' . $id, $edit, t('Save'));
$this->drupalPostForm($entity_type . '/manage/' . $id . '/edit', $edit, t('Save'));
// Check that the new revision has the expected values.
$this->container->get('entity.manager')->getStorage($entity_type)->resetCache(array($id));
......@@ -630,7 +630,7 @@ function testHiddenField() {
->save();
// Display edit form.
$this->drupalGet($entity_type . '/manage/' . $id);
$this->drupalGet($entity_type . '/manage/' . $id . '/edit');
$this->assertFieldByName("{$field_name}[0][value]", 99, 'Widget is displayed with the correct default value');
// Update the entity.
......@@ -649,7 +649,7 @@ function testHiddenField() {
// Create a new revision.
$edit = array('revision' => TRUE);
$this->drupalPostForm($entity_type . '/manage/' . $id, $edit, t('Save'));
$this->drupalPostForm($entity_type . '/manage/' . $id . '/edit', $edit, t('Save'));
// Check that the expected value has been carried over to the new revision.
\Drupal::entityManager()->getStorage($entity_type)->resetCache(array($id));
......
......@@ -114,7 +114,7 @@ function testFieldFormTranslationRevisions() {
"{$field_name}[0][value]" => $entity->{$field_name}->value,
'revision' => TRUE,
);
$this->drupalPostForm($this->entityTypeId . '/manage/' . $entity->id(), $edit, t('Save'));
$this->drupalPostForm($this->entityTypeId . '/manage/' . $entity->id() . '/edit', $edit, t('Save'));
// Check translation revisions.
$this->checkTranslationRevisions($entity->id(), $entity->getRevisionId(), $available_langcodes);
......
......@@ -318,7 +318,7 @@ function testLinkTitle() {
$edit = array(
"{$field_name}[0][title]" => $title,
);
$this->drupalPostForm("entity_test/manage/$id", $edit, t('Save'));
$this->drupalPostForm("entity_test/manage/$id/edit", $edit, t('Save'));
$this->assertText(t('entity_test @id has been updated.', array('@id' => $id)));
$this->renderTestEntity($id);
......
......@@ -25,7 +25,7 @@ function testSelectListDynamic() {
$this->drupalLogin($web_user);
// Display form.
$this->drupalGet('entity_test_rev/manage/' . $this->entity->id());
$this->drupalGet('entity_test_rev/manage/' . $this->entity->id() . '/edit');
$options = $this->xpath('//select[@id="edit-test-options"]/option');
$this->assertEqual(count($options), count($this->test) + 1);
foreach ($options as $option) {
......
......@@ -26,7 +26,7 @@ class EntityFormTest extends WebTestBase {
protected function setUp() {
parent::setUp();
$web_user = $this->drupalCreateUser(array('administer entity_test content'));
$web_user = $this->drupalCreateUser(array('administer entity_test content', 'view test entity'));
$this->drupalLogin($web_user);
// Add a language.
......@@ -84,14 +84,14 @@ protected function doTestFormCRUD($entity_type) {
$this->assertTrue($entity, format_string('%entity_type: Entity found in the database.', array('%entity_type' => $entity_type)));
$edit['name[0][value]'] = $name2;
$this->drupalPostForm($entity_type . '/manage/' . $entity->id(), $edit, t('Save'));
$this->drupalPostForm($entity_type . '/manage/' . $entity->id() . '/edit', $edit, t('Save'));
$entity = $this->loadEntityByName($entity_type, $name1);
$this->assertFalse($entity, format_string('%entity_type: The entity has been modified.', array('%entity_type' => $entity_type)));
$entity = $this->loadEntityByName($entity_type, $name2);
$this->assertTrue($entity, format_string('%entity_type: Modified entity found in the database.', array('%entity_type' => $entity_type)));
$this->assertNotEqual($entity->name->value, $name1, format_string('%entity_type: The entity name has been modified.', array('%entity_type' => $entity_type)));
$this->drupalGet($entity_type . '/manage/' . $entity->id());
$this->drupalGet($entity_type . '/manage/' . $entity->id() . '/edit');
$this->clickLink(t('Delete'));
$this->drupalPostForm(NULL, array(), t('Delete'));
$entity = $this->loadEntityByName($entity_type, $name2);
......@@ -125,12 +125,12 @@ protected function doTestMultilingualFormCRUD($entity_type_id) {
$this->assertEqual($translated_entity->name->value, $name1_ro, format_string('%entity_type: The translation has been added.', array('%entity_type' => $entity_type_id)));
$edit['name[0][value]'] = $name2_ro;
$this->drupalPostForm('ro/' . $entity_type_id . '/manage/' . $entity->id(), $edit, t('Save'));
$this->drupalPostForm('ro/' . $entity_type_id . '/manage/' . $entity->id() . '/edit', $edit, t('Save'));
$translated_entity = $this->loadEntityByName($entity_type_id, $name1)->getTranslation('ro');
$this->assertTrue($translated_entity, format_string('%entity_type: Modified translation found in the database.', array('%entity_type' => $entity_type_id)));
$this->assertEqual($translated_entity->name->value, $name2_ro, format_string('%entity_type: The name of the translation has been modified.', array('%entity_type' => $entity_type_id)));
$this->drupalGet('ro/' . $entity_type_id . '/manage/' . $entity->id());
$this->drupalGet('ro/' . $entity_type_id . '/manage/' . $entity->id() . '/edit');
$this->clickLink(t('Delete'));
$this->drupalPostForm(NULL, array(), t('Delete Romanian translation'));
$entity = $this->loadEntityByName($entity_type_id, $name1);
......
......@@ -37,6 +37,7 @@ protected function setUp() {
// Create and login user.
$this->webUser = $this->drupalCreateUser(array(
'administer entity_test content',
'view test entity',
));
$this->drupalLogin($this->webUser);
}
......@@ -110,7 +111,7 @@ protected function runRevisionsTests($entity_type) {
// Confirm the correct revision text appears in the edit form.
$entity = entity_load($entity_type, $entity->id->value