diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldFormatterTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldFormatterTest.php new file mode 100644 index 0000000..335f833 --- /dev/null +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldFormatterTest.php @@ -0,0 +1,394 @@ + 'Entity Reference field formatter', + 'description' => 'Tests for the field formatters provided by Entity Reference.', + 'group' => 'Entity Reference', + ); + } + + public static $modules = array('node', 'entity_reference', 'entity_reference_test'); + + /** + * Field definitions, instances and display options. + * + * @var array + */ + protected $fields = array(); + + /** + * XPath query string to retrieve the div.field-item elements. + * + * There are placeholders for node ID and ield name. + * + * @var string + */ + protected $fieldItemXPathQuery = '//*[@id=:id]/div[@class="content"]/div[contains(@class, :field_name)]/div[@class="field-items"]/div[starts-with(@class, "field-item")]'; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->drupalLogin($this->root_user); + + // Create an Article node type. + $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + + // Create fields for each entity reference field formatters. + $this->fields = array( + 'test_entity_id' => array( + 'field' => NULL, + 'instance' => NULL, + 'display_options' => array( + 'default' => array( + 'type' => 'entity_reference_entity_id', + 'settings' => array(), + ), + 'teaser' => array( + 'type' => 'entity_reference_entity_id', + 'settings' => array(), + ), + ), + ), + 'test_label' => array( + 'field' => NULL, + 'instance' => NULL, + 'display_options' => array( + 'default' => array( + 'type' => 'entity_reference_label', + 'settings' => array( + 'link' => FALSE, + ), + ), + 'teaser' => array( + 'type' => 'entity_reference_label', + 'settings' => array( + 'link' => FALSE, + ), + ), + ), + ), + 'test_entity_view' => array( + 'field' => NULL, + 'instance' => NULL, + 'display_options' => array( + 'default' => array( + 'type' => 'entity_reference_entity_view', + 'settings' => array( + 'view_mode' => 'default', + 'links' => FALSE, + ), + ), + 'teaser' => array( + 'type' => 'entity_reference_entity_view', + 'settings' => array( + 'view_mode' => 'default', + 'links' => FALSE, + ), + ), + ), + ), + ); + + foreach (array_keys($this->fields) as $field_name) { + $this->fields[$field_name]['field'] = entity_create('field_entity', array( + 'name' => $field_name, + 'type' => 'entity_reference', + 'cardinality' => FIELD_CARDINALITY_UNLIMITED, + 'entity_type' => 'node', + 'entity_types' => array(), + 'translatable' => FALSE, + 'settings' => array( + 'target_type' => 'node', + ), + )); + $this->fields[$field_name]['field']->save(); + + $this->fields[$field_name]['instance'] = entity_create('field_instance', array( + 'label' => 'ER formatter - ' . $this->fields[$field_name]['display_options']['default']['type'], + 'field_name' => $field_name, + 'entity_type' => 'node', + 'bundle' => 'article', + 'settings' => array( + 'handler' => 'default', + 'handler_settings' => array( + 'target_bundles' => array('article'), + ), + ), + )); + $this->fields[$field_name]['instance']->save(); + + foreach ($this->fields[$field_name]['display_options'] as $view_mode => $display_options) { + $display = entity_get_display( + $this->fields[$field_name]['instance']['entity_type'], + $this->fields[$field_name]['instance']['bundle'], + $view_mode + ); + $display->setComponent($field_name, $display_options)->save(); + } + } + } + + /** + * Render an entity and see the formatters do what we want. + */ + public function testRender() { + // Build a set of test data. + $children = array( + 'child_01' => array( + 'type' => 'article', + 'status' => NODE_PUBLISHED, + 'title' => 'Child 01', + 'uid' => 1, + ), + 'child_02' => array( + 'type' => 'article', + 'status' => NODE_NOT_PUBLISHED, + 'title' => 'Child 02', + 'uid' => 1, + ), + ); + $children_count = count($children); + + $parent = array( + 'type' => 'article', + 'status' => NODE_PUBLISHED, + 'title' => 'Parent 01', + 'uid' => 1, + ); + + // Create the children and initialize the parent values. + foreach ($children as $key => $values) { + $children[$key] = entity_create('node', $values); + $children[$key]->save(); + + foreach (array_keys($this->fields) as $field_name) { + $parent[$field_name][] = array('target_id' => $children[$key]->id()); + } + } + + // Create the parent. + $parent = entity_create('node', $parent); + $parent->save(); + + // We expect this. + $expected = array( + 'admin' => array( + 'test_entity_id' => array( + 'count' => $children_count, + 'items' => array(), + ), + 'test_label' => array( + 'count' => $children_count, + 'items' => array(), + ), + 'test_entity_view' => array( + 'count' => $children_count, + 'items' => array(), + ), + ), + 'anonymous' => array( + 'test_entity_id' => array( + 'count' => 0, + 'items' => array(), + ), + 'test_label' => array( + 'count' => 0, + 'items' => array(), + ), + 'test_entity_view' => array( + 'count' => 0, + 'items' => array(), + ), + ), + ); + foreach ($children as $child) { + $accounts = array('admin'); + if ($child->isPublished()) { + $accounts[] = 'anonymous'; + foreach (array_keys($this->fields) as $field_name) { + $expected['anonymous'][$field_name]['count']++; + } + } + + foreach ($accounts as $account) { + $expected[$account]['test_entity_id']['items'][] = $child->id(); + $expected[$account]['test_label']['items'][] = $child->label(); + $expected[$account]['test_entity_view']['items'][] = array( + 'id' => $child->id(), + ); + } + } + + $this->drupalLogout(); + $this->assertNodeView($parent, 'anonymous', $expected); + + $this->drupalLogin($this->root_user); + $this->assertNodeView($parent, 'admin', $expected); + } + + /** + * @param \Drupal\core\Entity\EntityInterface $node + * @param string $account + * @param array $expected + */ + protected function assertNodeView($node, $account, $expected) { + $view_mode = 'full'; + $path = 'node/' . $node->id() . '/entity-reference-test-field-formatter/' . $view_mode; + $this->drupalGet($path); + + $xpath_arguments = array( + ':id' => 'node-' . $node->id(), + ':field_name' => NULL, + ); + + // Check formatter: entity_reference_entity_id. + $field_name = 'test_entity_id'; + $xpath_arguments[':field_name'] = 'field-name-' . drupal_html_class($this->fields[$field_name]['field']->name); + $xpath_result = $this->xpath($this->fieldItemXPathQuery, $xpath_arguments); + $this->assertFormatterEntityId($this->fields[$field_name], $xpath_result, $account, $expected[$account][$field_name]); + + // Check formatter: entity_reference_label. + $field_name = 'test_label'; + $xpath_arguments[':field_name'] = 'field-name-' . drupal_html_class($this->fields[$field_name]['field']->name); + $xpath_result = $this->xpath($this->fieldItemXPathQuery, $xpath_arguments); + $this->assertFormatterLabel($this->fields[$field_name], $xpath_result, $account, $expected[$account][$field_name]); + + // Check formatter: entity_reference_entity_view. + $field_name = 'test_entity_view'; + $xpath_arguments[':field_name'] = 'field-name-' . drupal_html_class($this->fields[$field_name]['field']->name); + $xpath_result = $this->xpath($this->fieldItemXPathQuery, $xpath_arguments); + $this->assertFormatterEntityView($this->fields[$field_name], $xpath_result, $account, $expected[$account][$field_name]); + } + + /** + * @param array $field + * @param SimpleXMLElement[] $xpath_result + * @param string $account + * @param array $expected + */ + protected function assertFormatterEntityId($field, $xpath_result, $account, $expected) { + $xpath_result_count = count($xpath_result); + $this->assertEqual( + $expected['count'], + $xpath_result_count, + format_string( + 'Number of items in field @field_name. Account: @account; Expected: @expected; Presented: @presented;', + array( + '@field_name' => $field['field']->name, + '@account' => $account, + '@expected' => $expected['count'], + '@presented' => $xpath_result_count, + ) + ) + ); + + $count = min($xpath_result_count, $expected['count']); + for ($i = 0; $i < $count; $i++) { + $this->assertEqual( + $expected['items'][$i], + (string) $xpath_result[$i], + format_string( + 'Referenced entity is founded in field @field_name, in position @delta. Account: @account; Expected: @expected; Presented: @presented;', + array( + '@field_name' => $field['field']->name, + '@delta' => $i, + '@account' => $account, + '@expected' => $expected['items'][$i], + '@presented' => (string) $xpath_result[$i], + ) + ) + ); + } + } + + /** + * @param array $field + * @param SimpleXMLElement[] $xpath_result + * @param string $account + * @param array $expected + */ + protected function assertFormatterLabel($field, $xpath_result, $account, $expected) { + $this->assertFormatterEntityId($field, $xpath_result, $account, $expected); + } + + /** + * @param array $field + * @param SimpleXMLElement[] $xpath_result + * @param string $account + * @param array $expected + */ + protected function assertFormatterEntityView($field, $xpath_result, $account, $expected) { + $xpath_result_count = count($xpath_result); + $this->assertEqual( + $expected['count'], + $xpath_result_count, + format_string( + 'Number of items in field @field_name. Account: @account; Expected: @expected; Presented: @presented;', + array( + '@field_name' => $field['field']->name, + '@account' => $account, + '@expected' => $expected['count'], + '@presented' => $xpath_result_count, + ) + ) + ); + + $count = min($xpath_result_count, $expected['count']); + for ($i = 0; $i < $count; $i++) { + $id = 'node-' . $expected['items'][$i]['id']; + $xpath_result_item = $xpath_result[$i]->xpath('*[@id="' . $id . '"]'); + + if (count($xpath_result_item) == 1) { + $this->assertEqual( + $id, + $xpath_result_item[0]->attributes()->id, + format_string( + 'Referenced entity is founded in field @field_name, in position @delta. Account: @account; Expected: @expected; Presented: @presented;', + array( + '@field_name' => $field['field']->name, + '@delta' => $i, + '@account' => $account, + '@expected' => $id, + '@presented' => $xpath_result_item[0]->attributes()->id, + ) + ) + ); + } + else { + $this->assert('fail', + format_string( + 'Number of rendered entity is @count in field @field_name, in position @delta. Account: @account.', + array( + '@count' => count($xpath_result_item), + '@field_name' => $field['field']->name, + '@delta' => $i, + '@account' => $account, + ) + ) + ); + } + } + } + +} diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test/entity_reference_test.module b/core/modules/entity_reference/tests/modules/entity_reference_test/entity_reference_test.module index 37dc050..ba17dad 100644 --- a/core/modules/entity_reference/tests/modules/entity_reference_test/entity_reference_test.module +++ b/core/modules/entity_reference/tests/modules/entity_reference_test/entity_reference_test.module @@ -4,3 +4,60 @@ * @file * Helper module for the Entity Reference tests. */ + +use Drupal\Core\Entity\EntityInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; + +/** + * Implements hook_menu(). + */ +function entity_reference_test_menu() { + $items = array(); + + $items['node/%node/entity-reference-test-field-formatter'] = array( + 'title' => 'Test Entity reference field formatter', + 'page callback' => 'entity_reference_test_field_formatter_page', + 'page arguments' => array(1, 3), + 'access callback' => TRUE, + 'type' => MENU_LOCAL_TASK, + 'weight' => 99, + ); + + return $items; +} + +/** + * Display a node with different view modes. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * Entity to display + * + * @param string $view_mode + * Entity view mode identifier. + * + * @throws NotFoundHttpException + * + * @return array + * Render array. + */ +function entity_reference_test_field_formatter_page(EntityInterface $entity, $view_mode = NULL) { + $return = array(); + + if (!$view_mode) { + $view_mode = 'default'; + } + else { + $view_modes = entity_get_view_modes($entity->entityType()); + if (!array_key_exists($view_mode, $view_modes)) { + throw new NotFoundHttpException(); + } + } + + $return[$view_mode] = entity_view($entity, $view_mode); + + // Save the entity to see the field formatters does not do any modification on + // the entity. + $entity->save(); + + return $return; +}