ViewTestBase.php 10.1 KB
Newer Older
1
<?php
2

3 4
/**
 * @file
5
 * Contains \Drupal\views\Tests\ViewTestBase.
6 7
 */

8
namespace Drupal\views\Tests;
9

10
use Drupal\Core\Database\Query\SelectInterface;
11
use Drupal\simpletest\WebTestBase;
12
use Drupal\views\ViewExecutable;
13
use Drupal\block\Entity\Block;
14

15
/**
16 17 18 19 20 21 22 23
 * Defines a base class for Views testing in the full web test environment.
 *
 * Use this base test class if you need to emulate a full Drupal installation.
 * When possible, ViewUnitTestBase should be used instead. Both base classes
 * include the same methods.
 *
 * @see \Drupal\views\Tests\ViewUnitTestBase
 * @see \Drupal\simpletest\WebTestBase
24
 */
25
abstract class ViewTestBase extends WebTestBase {
26

27 28 29 30 31
  /**
   * Modules to enable.
   *
   * @var array
   */
32
  public static $modules = array('views', 'views_test_config');
33

34
  protected function setUp() {
35
    parent::setUp();
36

37 38 39 40
    // Ensure that the plugin definitions are cleared.
    foreach (ViewExecutable::getPluginTypes() as $plugin_type) {
      $this->container->get("plugin.manager.views.$plugin_type")->clearCachedDefinitions();
    }
41
    ViewTestData::createTestViews(get_class($this), array('views_test_config'));
42 43
  }

44
  /**
45
   * Sets up the views_test_data.module.
46
   *
47 48
   * Because the schema of views_test_data.module is dependent on the test
   * using it, it cannot be enabled normally.
49 50 51
   */
  protected function enableViewsTestModule() {
    // Define the schema and views data variable before enabling the test module.
52 53
    \Drupal::state()->set('views_test_data_schema', $this->schemaDefinition());
    \Drupal::state()->set('views_test_data_views_data', $this->viewsData());
54

55
    \Drupal::moduleHandler()->install(array('views_test_data'));
56
    $this->resetAll();
57 58
    $this->rebuildContainer();
    $this->container->get('module_handler')->reload();
59 60 61

    // Load the test dataset.
    $data_set = $this->dataSet();
62
    $query = db_insert('views_test_data')
63 64 65 66 67 68 69 70
      ->fields(array_keys($data_set[0]));
    foreach ($data_set as $record) {
      $query->values($record);
    }
    $query->execute();
    $this->checkPermissions(array(), TRUE);
  }

71
  /**
72
   * Verifies that a result set returned by a View matches expected values.
73 74 75 76 77
   *
   * The comparison is done on the string representation of the columns of the
   * column map, taking the order of the rows into account, but not the order
   * of the columns.
   *
78 79 80 81 82 83 84 85 86 87 88 89 90
   * @param \Drupal\views\ViewExecutable $view
   *   An executed View.
   * @param array $expected_result
   *   An expected result set.
   * @param array $column_map
   *   (optional) An associative array mapping the columns of the result set
   *   from the view (as keys) and the expected result set (as values).
   * @param string $message
   *   (optional) A custom message to display with the assertion. Defaults to
   *   'Identical result set.'
   *
   * @return bool
   *   TRUE if the assertion succeeded, or FALSE otherwise.
91
   */
92
  protected function assertIdenticalResultset($view, $expected_result, $column_map = array(), $message = 'Identical result set.') {
93 94 95 96
    return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, 'assertIdentical');
  }

  /**
97
   * Verifies that a result set returned by a View differs from certain values.
98 99 100
   *
   * Inverse of ViewsTestCase::assertIdenticalResultset().
   *
101 102 103 104 105 106 107 108 109 110 111 112 113
   * @param \Drupal\views\ViewExecutable $view
   *   An executed View.
   * @param array $expected_result
   *   An expected result set.
   * @param array $column_map
   *   (optional) An associative array mapping the columns of the result set
   *  from the view (as keys) and the expected result set (as values).
   * @param string $message
   *   (optional) A custom message to display with the assertion. Defaults to
   *   'Non-identical result set.'
   *
   * @return bool
   *   TRUE if the assertion succeeded, or FALSE otherwise.
114
   */
115
  protected function assertNotIdenticalResultset($view, $expected_result, $column_map = array(), $message = 'Non-identical result set.') {
116 117 118
    return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, 'assertNotIdentical');
  }

119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
  /**
   * Performs View result assertions.
   *
   * This is a helper method for ViewTestBase::assertIdenticalResultset() and
   * ViewTestBase::assertNotIdenticalResultset().
   *
   * @param \Drupal\views\ViewExecutable $view
   *   An executed View.
   * @param array $expected_result
   *   An expected result set.
   * @param array $column_map
   *   An associative array mapping the columns of the result set
   *   from the view (as keys) and the expected result set (as values).
   * @param string $message
   *   The message to display with the assertion.
   * @param string $assert_method
   *   The TestBase assertion method to use (either 'assertIdentical' or
   *   'assertNotIdentical').
   *
   * @return bool
   *   TRUE if the assertion succeeded, or FALSE otherwise.
   *
   * @see \Drupal\views\Tests\ViewTestBase::assertIdenticalResultset()
   * @see \Drupal\views\Tests\ViewTestBase::assertNotIdenticalResultset()
   */
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
  protected function assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, $assert_method) {
    // Convert $view->result to an array of arrays.
    $result = array();
    foreach ($view->result as $key => $value) {
      $row = array();
      foreach ($column_map as $view_column => $expected_column) {
        // The comparison will be done on the string representation of the value.
        $row[$expected_column] = (string) $value->$view_column;
      }
      $result[$key] = $row;
    }

    // Remove the columns we don't need from the expected result.
    foreach ($expected_result as $key => $value) {
      $row = array();
      foreach ($column_map as $expected_column) {
        // The comparison will be done on the string representation of the value.
        $row[$expected_column] = (string) (is_object($value) ? $value->$expected_column : $value[$expected_column]);
      }
      $expected_result[$key] = $row;
    }

    // Reset the numbering of the arrays.
    $result = array_values($result);
    $expected_result = array_values($expected_result);

    $this->verbose('<pre>Returned data set: ' . print_r($result, TRUE) . "\n\nExpected: ". print_r($expected_result, TRUE));

    // Do the actual comparison.
    return $this->$assert_method($result, $expected_result, $message);
  }

  /**
177 178 179 180 181 182 183 184 185 186 187 188 189
   * Orders a nested array containing a result set based on a given column.
   *
   * @param array $result_set
   *   An array of rows from a result set, with each row as an associative
   *   array keyed by column name.
   * @param string $column
   *   The column name by which to sort the result set.
   * @param bool $reverse
   *   (optional) Boolean indicating whether to sort the result set in reverse
   *   order. Defaults to FALSE.
   *
   * @return array
   *   The sorted result set.
190 191
   */
  protected function orderResultSet($result_set, $column, $reverse = FALSE) {
192 193 194 195 196 197 198
    $order = $reverse ? -1 : 1;
    usort($result_set, function ($a, $b) use ($column, $order) {
      if ($a[$column] == $b[$column]) {
        return 0;
      }
      return $order * (($a[$column] < $b[$column]) ? -1 : 1);
    });
199 200 201 202
    return $result_set;
  }

  /**
203 204 205 206 207 208 209 210 211 212 213
   * Asserts the existence of a button with a certain ID and label.
   *
   * @param string $id
   *   The HTML ID of the button
   * @param string $label.
   *   The expected label for the button.
   * @param string $message
   *   (optional) A custom message to display with the assertion. If no custom
   *   message is provided, the message will indicate the button label.
   *
   * @return bool
214
   *   TRUE if the asserion was successful, or FALSE on failure.
215 216 217 218 219 220
   */
  protected function helperButtonHasLabel($id, $expected_label, $message = 'Label has the expected value: %label.') {
    return $this->assertFieldById($id, $expected_label, t($message, array('%label' => $expected_label)));
  }

  /**
221
   * Executes a view with debugging.
222
   *
223 224
   * @param \Drupal\views\ViewExecutable $view
   *   The view object.
225
   * @param array $args
226
   *   (optional) An array of the view arguments to use for the view.
227 228
   */
  protected function executeView($view, $args = array()) {
229 230 231
    // A view does not really work outside of a request scope, due to many
    // dependencies like the current user.
    $this->container->enterScope('request');
232 233
    $view->setDisplay();
    $view->preExecute($args);
234
    $view->execute();
235 236 237 238 239
    $verbose_message = '<pre>Executed view: ' . ((string) $view->build_info['query']). '</pre>';
    if ($view->build_info['query'] instanceof SelectInterface) {
      $verbose_message .= '<pre>Arguments: ' . print_r($view->build_info['query']->getArguments(), TRUE) . '</pre>';
    }
    $this->verbose($verbose_message);
240 241
  }

242 243 244
  /**
   * Checks to see whether a block appears on the page.
   *
245
   * @param \Drupal\block\Entity\Block $block
246 247 248 249 250 251 252 253 254 255
   *   The block entity to find on the page.
   */
  protected function assertBlockAppears(Block $block) {
    $result = $this->findBlockInstance($block);
    $this->assertTrue(!empty($result), format_string('Ensure the block @id appears on the page', array('@id' => $block->id())));
  }

  /**
   * Checks to see whether a block does not appears on the page.
   *
256
   * @param \Drupal\block\Entity\Block $block
257 258 259 260 261 262 263 264 265 266
   *   The block entity to find on the page.
   */
  protected function assertNoBlockAppears(Block $block) {
    $result = $this->findBlockInstance($block);
    $this->assertFalse(!empty($result), format_string('Ensure the block @id does not appear on the page', array('@id' => $block->id())));
  }

  /**
   * Find a block instance on the page.
   *
267
   * @param \Drupal\block\Entity\Block $block
268 269 270 271 272 273
   *   The block entity to find on the page.
   *
   * @return array
   *   The result from the xpath query.
   */
  protected function findBlockInstance(Block $block) {
274
    return $this->xpath('//div[@id = :id]', array(':id' => 'block-' . $block->id()));
275 276
  }

277
  /**
278
   * Returns the schema definition.
279 280
   */
  protected function schemaDefinition() {
281
    return ViewTestData::schemaDefinition();
282 283 284
  }

  /**
285
   * Returns the views data definition.
286 287
   */
  protected function viewsData() {
288
    return ViewTestData::viewsData();
289 290 291
  }

  /**
292
   * Returns a very simple test dataset.
293 294
   */
  protected function dataSet() {
295
    return ViewTestData::dataSet();
296 297 298
  }

}