123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- <?php
- /**
- * @file
- * Tests the fieldapi integration of viewsdata.
- */
- /**
- * @todo Test on a generic entity not on a node.
- *
- * What has to be tested:
- * - Take sure that every wanted field is added to the according entity type.
- * - Take sure the joins are done correct.
- * - Use basic fields and take sure that the full wanted object is build.
- * - Use relationships between different entity types, for example node and
- * the node author(user).
- */
- /**
- * Provides some helper methods for testing fieldapi integration into views.
- */
- class ViewsFieldApiTestHelper extends ViewsSqlTest {
- /**
- * Stores the field definitions used by the test.
- *
- * @var array
- */
- public $fields;
- /**
- * Stores the instances of the fields. They have
- * the same keys as the fields.
- *
- * @var array
- */
- public $instances;
- /**
- *
- */
- protected function createUser($extra_edit = array()) {
- $permissions = array('access comments', 'access content', 'post comments', 'skip comment approval');
- // Create a role with the given permission set.
- if (!($rid = $this->drupalCreateRole($permissions))) {
- return FALSE;
- }
- // Create a user assigned to that role.
- $edit = array();
- $edit['name'] = $this->randomName();
- $edit['mail'] = $edit['name'] . '@example.com';
- $edit['roles'] = array($rid => $rid);
- $edit['pass'] = user_password();
- $edit['status'] = 1;
- $edit += $extra_edit;
- $account = user_save(drupal_anonymous_user(), $edit);
- $this->assertTrue(!empty($account->uid), t('User created with name %name and pass %pass', array('%name' => $edit['name'], '%pass' => $edit['pass'])), t('User login'));
- if (empty($account->uid)) {
- return FALSE;
- }
- // Add the raw password so that we can log in as this user.
- $account->pass_raw = $edit['pass'];
- return $account;
- }
- function setUpFields($amount = 3) {
- // Create three fields.
- $field_names = array();
- for ($i = 0; $i < $amount; $i++) {
- $field_names[$i] = 'field_name_' . $i;
- $field = array('field_name' => $field_names[$i], 'type' => 'text');
- $this->fields[$i] = $field = field_create_field($field);
- }
- return $field_names;
- }
- function setUpInstances($bundle = 'page') {
- foreach ($this->fields as $key => $field) {
- $instance = array(
- 'field_name' => $field['field_name'],
- 'entity_type' => 'node',
- 'bundle' => 'page',
- );
- $this->instances[$key] = field_create_instance($instance);
- }
- }
- /**
- * Clear all views caches and static caches which are required for the patch.
- */
- function clearViewsCaches() {
- // Reset views data cache.
- drupal_static_reset('_views_fetch_data_cache');
- drupal_static_reset('_views_fetch_data_recursion_protected');
- drupal_static_reset('_views_fetch_data_fully_loaded');
- }
- }
- /**
- * Test the produced views_data.
- */
- class viewsFieldApiDataTest extends ViewsFieldApiTestHelper {
- /**
- * Stores the fields for this test case.
- */
- var $fields;
- public static function getInfo() {
- return array(
- 'name' => 'Fieldapi: Views Data',
- 'description' => 'Tests the fieldapi views data.',
- 'group' => 'Views Modules',
- );
- }
- function setUp() {
- parent::setUp();
- $langcode = LANGUAGE_NONE;
- $field_names = $this->setUpFields();
- // The first one will be attached to nodes only.
- $instance = array(
- 'field_name' => $field_names[0],
- 'entity_type' => 'node',
- 'bundle' => 'page',
- );
- field_create_instance($instance);
- // The second one will be attached to users only.
- $instance = array(
- 'field_name' => $field_names[1],
- 'entity_type' => 'user',
- 'bundle' => 'user',
- );
- field_create_instance($instance);
- // The third will be attached to both nodes and users.
- $instance = array(
- 'field_name' => $field_names[2],
- 'entity_type' => 'node',
- 'bundle' => 'page',
- );
- field_create_instance($instance);
- $instance = array(
- 'field_name' => $field_names[2],
- 'entity_type' => 'user',
- 'bundle' => 'user',
- );
- field_create_instance($instance);
- // Now create some example nodes/users for the view result.
- for ($i = 0; $i < 5; $i++) {
- $edit = array(
- // @todo Write a helper method to create such values.
- 'field_name_0' => array($langcode => array((array('value' => $this->randomName())))),
- 'field_name_2' => array($langcode => array((array('value' => $this->randomName())))),
- );
- $this->nodes[] = $this->drupalCreateNode($edit);
- }
- for ($i = 0; $i < 5; $i++) {
- $edit = array(
- 'field_name_1' => array($langcode => array((array('value' => $this->randomName())))),
- 'field_name_2' => array($langcode => array((array('value' => $this->randomName())))),
- );
- $this->users[] = $this->createUser($edit);
- }
- // Reset views data cache.
- $this->clearViewsCaches();
- }
- /**
- * Unit testing the views data structure.
- *
- * We check data structure for both node and node revision tables.
- */
- function testViewsData() {
- $data = views_fetch_data();
- // Check the table and the joins of the first field.
- // Attached to node only.
- $field = $this->fields[0];
- $current_table = _field_sql_storage_tablename($field);
- $revision_table = _field_sql_storage_revision_tablename($field);
- $this->assertTrue(isset($data[$current_table]));
- $this->assertTrue(isset($data[$revision_table]));
- // The node field should join against node.
- $this->assertTrue(isset($data[$current_table]['table']['join']['node']));
- $this->assertTrue(isset($data[$revision_table]['table']['join']['node_revision']));
- $expected_join = array(
- 'left_field' => 'nid',
- 'field' => 'entity_id',
- 'extra' => array(
- array('field' => 'entity_type', 'value' => 'node'),
- array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE),
- ),
- );
- $this->assertEqual($expected_join, $data[$current_table]['table']['join']['node']);
- $expected_join = array(
- 'left_field' => 'vid',
- 'field' => 'revision_id',
- 'extra' => array(
- array('field' => 'entity_type', 'value' => 'node'),
- array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE),
- ),
- );
- $this->assertEqual($expected_join, $data[$revision_table]['table']['join']['node_revision']);
- // Check the table and the joins of the second field.
- // Attached to both node and user.
- $field_2 = $this->fields[2];
- $current_table_2 = _field_sql_storage_tablename($field_2);
- $revision_table_2 = _field_sql_storage_revision_tablename($field_2);
- $this->assertTrue(isset($data[$current_table_2]));
- $this->assertTrue(isset($data[$revision_table_2]));
- // The second field should join against both node and users.
- $this->assertTrue(isset($data[$current_table_2]['table']['join']['node']));
- $this->assertTrue(isset($data[$revision_table_2]['table']['join']['node_revision']));
- $this->assertTrue(isset($data[$current_table_2]['table']['join']['users']));
- $expected_join = array(
- 'left_field' => 'nid',
- 'field' => 'entity_id',
- 'extra' => array(
- array('field' => 'entity_type', 'value' => 'node'),
- array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE),
- ),
- );
- $this->assertEqual($expected_join, $data[$current_table_2]['table']['join']['node']);
- $expected_join = array(
- 'left_field' => 'vid',
- 'field' => 'revision_id',
- 'extra' => array(
- array('field' => 'entity_type', 'value' => 'node'),
- array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE),
- ),
- );
- $this->assertEqual($expected_join, $data[$revision_table_2]['table']['join']['node_revision']);
- $expected_join = array(
- 'left_field' => 'uid',
- 'field' => 'entity_id',
- 'extra' => array(
- array('field' => 'entity_type', 'value' => 'user'),
- array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE),
- ),
- );
- $this->assertEqual($expected_join, $data[$current_table_2]['table']['join']['users']);
- // @todo Check the fields.
- // @todo Check the arguments.
- // @todo Check the sort criterias.
- // @todo Check the relationships.
- }
- }
- /**
- * Tests the field_field handler.
- *
- * @todo Check a entity-type with bundles.
- * @todo Check a entity-type without bundles.
- * @todo Check locale:disabled, locale:enabled and locale:enabled with another language.
- * @todo Check revisions.
- */
- class viewsHandlerFieldFieldTest extends ViewsFieldApiTestHelper {
- public $nodes;
- public static function getInfo() {
- return array(
- 'name' => 'Fieldapi: Field handler',
- 'description' => 'Tests the field itself of the fieldapi integration',
- 'group' => 'Views Modules',
- );
- }
- protected function setUp() {
- parent::setUp();
- // Setup basic fields.
- $this->setUpFields(3);
- // Setup a field with cardinality > 1.
- $this->fields[3] = $field = field_create_field(array('field_name' => 'field_name_3', 'type' => 'text', 'cardinality' => FIELD_CARDINALITY_UNLIMITED));
- // Setup a field that will have no value.
- $this->fields[4] = $field = field_create_field(array('field_name' => 'field_name_4', 'type' => 'text', 'cardinality' => FIELD_CARDINALITY_UNLIMITED));
- $this->setUpInstances();
- $this->clearViewsCaches();
- // Create some nodes.
- $this->nodes = array();
- for ($i = 0; $i < 3; $i++) {
- $edit = array('type' => 'page');
- for ($key = 0; $key < 3; $key++) {
- $field = $this->fields[$key];
- $edit[$field['field_name']][LANGUAGE_NONE][0]['value'] = $this->randomName(8);
- }
- for ($j = 0; $j < 5; $j++) {
- $edit[$this->fields[3]['field_name']][LANGUAGE_NONE][$j]['value'] = $this->randomName(8);
- }
- // Set this field to be empty.
- $edit[$this->fields[4]['field_name']] = array();
- $this->nodes[$i] = $this->drupalCreateNode($edit);
- }
- }
- public function testFieldRender() {
- $this->_testSimpleFieldRender();
- $this->_testFormatterSimpleFieldRender();
- $this->_testMultipleFieldRender();
- }
- public function _testSimpleFieldRender() {
- $view = $this->getFieldView();
- $this->executeView($view);
- // Tests that the rendered fields match the actual value of the fields.
- for ($i = 0; $i < 3; $i++) {
- for ($key = 0; $key < 2; $key++) {
- $field = $this->fields[$key];
- $rendered_field = $view->style_plugin->get_field($i, $field['field_name']);
- $expected_field = $this->nodes[$i]->{$field['field_name']}[LANGUAGE_NONE][0]['value'];
- $this->assertEqual($rendered_field, $expected_field);
- }
- }
- }
- /**
- * Tests that fields with formatters runs as expected.
- */
- public function _testFormatterSimpleFieldRender() {
- $view = $this->getFieldView();
- $view->display['default']->display_options['fields'][$this->fields[0]['field_name']]['type'] = 'text_trimmed';
- $view->display['default']->display_options['fields'][$this->fields[0]['field_name']]['settings'] = array(
- 'trim_length' => 3,
- );
- $this->executeView($view);
- // Take sure that the formatter works as expected.
- // @todo actually there should be a specific formatter.
- for ($i = 0; $i < 2; $i++) {
- $rendered_field = $view->style_plugin->get_field($i, $this->fields[0]['field_name']);
- $this->assertEqual(strlen($rendered_field), 3);
- }
- }
- public function _testMultipleFieldRender() {
- $view = $this->getFieldView();
- // Test delta limit.
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['group_rows'] = TRUE;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_limit'] = 3;
- $this->executeView($view);
- for ($i = 0; $i < 3; $i++) {
- $rendered_field = $view->style_plugin->get_field($i, $this->fields[3]['field_name']);
- $items = array();
- $pure_items = $this->nodes[$i]->{$this->fields[3]['field_name']}[LANGUAGE_NONE];
- $pure_items = array_splice($pure_items, 0, 3);
- foreach ($pure_items as $j => $item) {
- $items[] = $pure_items[$j]['value'];
- }
- $this->assertEqual($rendered_field, implode(', ', $items), 'Take sure that the amount of items are limited.');
- }
- // Test that an empty field is rendered without error.
- $rendered_field = $view->style_plugin->get_field(4, $this->fields[4]['field_name']);
- $view->destroy();
- // Test delta limit + offset.
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['group_rows'] = TRUE;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_limit'] = 3;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_offset'] = 1;
- $this->executeView($view);
- for ($i = 0; $i < 3; $i++) {
- $rendered_field = $view->style_plugin->get_field($i, $this->fields[3]['field_name']);
- $items = array();
- $pure_items = $this->nodes[$i]->{$this->fields[3]['field_name']}[LANGUAGE_NONE];
- $pure_items = array_splice($pure_items, 1, 3);
- foreach ($pure_items as $j => $item) {
- $items[] = $pure_items[$j]['value'];
- }
- $this->assertEqual($rendered_field, implode(', ', $items), 'Take sure that the amount of items are limited.');
- }
- $view->destroy();
- // Test delta limit + reverse.
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_offset'] = 0;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['group_rows'] = TRUE;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_limit'] = 3;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_reversed'] = TRUE;
- $this->executeView($view);
- for ($i = 0; $i < 3; $i++) {
- $rendered_field = $view->style_plugin->get_field($i, $this->fields[3]['field_name']);
- $items = array();
- $pure_items = $this->nodes[$i]->{$this->fields[3]['field_name']}[LANGUAGE_NONE];
- array_splice($pure_items, 0, -3);
- $pure_items = array_reverse($pure_items);
- foreach ($pure_items as $j => $item) {
- $items[] = $pure_items[$j]['value'];
- }
- $this->assertEqual($rendered_field, implode(', ', $items), 'Take sure that the amount of items are limited.');
- }
- $view->destroy();
- // Test delta first last.
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['group_rows'] = TRUE;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_limit'] = 0;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_first_last'] = TRUE;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_reversed'] = FALSE;
- $this->executeView($view);
- for ($i = 0; $i < 3; $i++) {
- $rendered_field = $view->style_plugin->get_field($i, $this->fields[3]['field_name']);
- $items = array();
- $pure_items = $this->nodes[$i]->{$this->fields[3]['field_name']}[LANGUAGE_NONE];
- $items[] = $pure_items[0]['value'];
- $items[] = $pure_items[4]['value'];
- $this->assertEqual($rendered_field, implode(', ', $items), 'Take sure that the amount of items are limited.');
- }
- $view->destroy();
- // Test delta limit + custom seperator.
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_first_last'] = FALSE;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['delta_limit'] = 3;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['group_rows'] = TRUE;
- $view->display['default']->display_options['fields'][$this->fields[3]['field_name']]['separator'] = ':';
- $this->executeView($view);
- for ($i = 0; $i < 3; $i++) {
- $rendered_field = $view->style_plugin->get_field($i, $this->fields[3]['field_name']);
- $items = array();
- $pure_items = $this->nodes[$i]->{$this->fields[3]['field_name']}[LANGUAGE_NONE];
- $pure_items = array_splice($pure_items, 0, 3);
- foreach ($pure_items as $j => $item) {
- $items[] = $pure_items[$j]['value'];
- }
- $this->assertEqual($rendered_field, implode(':', $items), 'Take sure that the amount of items are limited.');
- }
- }
- protected function getFieldView() {
- $view = new view();
- $view->name = 'view_fieldapi';
- $view->description = '';
- $view->tag = 'default';
- $view->base_table = 'node';
- $view->human_name = 'view_fieldapi';
- $view->core = 7;
- $view->api_version = '3.0';
- $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
- /* Display: Master */
- $handler = $view->new_display('default', 'Master', 'default');
- $handler->display->display_options['access']['type'] = 'perm';
- $handler->display->display_options['cache']['type'] = 'none';
- $handler->display->display_options['query']['type'] = 'views_query';
- $handler->display->display_options['exposed_form']['type'] = 'basic';
- $handler->display->display_options['pager']['type'] = 'full';
- $handler->display->display_options['style_plugin'] = 'default';
- $handler->display->display_options['row_plugin'] = 'fields';
- $handler->display->display_options['fields']['nid']['id'] = 'nid';
- $handler->display->display_options['fields']['nid']['table'] = 'node';
- $handler->display->display_options['fields']['nid']['field'] = 'nid';
- foreach ($this->fields as $key => $field) {
- $handler->display->display_options['fields'][$field['field_name']]['id'] = $field['field_name'];
- $handler->display->display_options['fields'][$field['field_name']]['table'] = 'field_data_' . $field['field_name'];
- $handler->display->display_options['fields'][$field['field_name']]['field'] = $field['field_name'];
- }
- return $view;
- }
- }
|