ModuleTest.php 14.9 KB
Newer Older
merlinofchaos's avatar
merlinofchaos committed
1 2
<?php

3
namespace Drupal\Tests\views\Kernel;
4

merlinofchaos's avatar
merlinofchaos committed
5 6
/**
 * Tests basic functions from the Views module.
7 8
 *
 * @group views
merlinofchaos's avatar
merlinofchaos committed
9
 */
10
use Drupal\views\Plugin\views\filter\Standard;
11
use Drupal\views\Views;
12
use Drupal\Component\Utility\SafeMarkup;
13
use Drupal\Component\Render\FormattableMarkup;
14

15
class ModuleTest extends ViewsKernelTestBase {
16

17 18 19 20 21
  /**
   * Views used by this test.
   *
   * @var array
   */
22
  public static $testViews = array('test_view_status', 'test_view', 'test_argument');
23

24 25 26 27 28
  /**
   * Modules to enable.
   *
   * @var array
   */
29
  public static $modules = ['field', 'user', 'block'];
30

31 32 33 34 35 36 37 38 39
  /**
   * Stores the last triggered error, for example via debug().
   *
   * @var string
   *
   * @see \Drupal\views\Tests\ModuleTest::errorHandler()
   */
  protected $lastErrorMessage;

merlinofchaos's avatar
merlinofchaos committed
40 41
  /**
   * Tests the views_get_handler method.
42 43
   *
   * @see views_get_handler()
merlinofchaos's avatar
merlinofchaos committed
44
   */
45
  public function testViewsGetHandler() {
merlinofchaos's avatar
merlinofchaos committed
46 47
    $types = array('field', 'area', 'filter');
    foreach ($types as $type) {
48
      $item = array(
49 50
        'table' => $this->randomMachineName(),
        'field' => $this->randomMachineName(),
51
      );
52
      $handler = $this->container->get('plugin.manager.views.' . $type)->getHandler($item);
53
      $this->assertEqual('Drupal\views\Plugin\views\\' . $type . '\Broken', get_class($handler), new FormattableMarkup('Make sure that a broken handler of type: @type is created.', ['@type' => $type]));
merlinofchaos's avatar
merlinofchaos committed
54 55 56
    }

    $views_data = $this->viewsData();
57
    $test_tables = array('views_test_data' => array('id', 'name'));
merlinofchaos's avatar
merlinofchaos committed
58 59 60
    foreach ($test_tables as $table => $fields) {
      foreach ($fields as $field) {
        $data = $views_data[$table][$field];
61 62 63 64
        $item = array(
          'table' => $table,
          'field' => $field,
        );
merlinofchaos's avatar
merlinofchaos committed
65 66
        foreach ($data as $id => $field_data) {
          if (!in_array($id, array('title', 'help'))) {
67
            $handler = $this->container->get('plugin.manager.views.' . $id)->getHandler($item);
merlinofchaos's avatar
merlinofchaos committed
68 69 70 71 72 73
            $this->assertInstanceHandler($handler, $table, $field, $id);
          }
        }
      }
    }

74
    // Test the override handler feature.
75 76 77 78
    $item = array(
      'table' => 'views_test_data',
      'field' => 'job',
    );
79
    $handler = $this->container->get('plugin.manager.views.filter')->getHandler($item, 'standard');
80 81
    $this->assertTrue($handler instanceof Standard);

82 83 84 85
    // @todo Reinstate these tests when the debug() in views_get_handler() is
    //   restored.
    return;

86 87 88 89 90 91
    // Test non-existent tables/fields.
    set_error_handler(array($this, 'customErrorHandler'));
    $item = array(
      'table' => 'views_test_data',
      'field' => 'field_invalid',
    );
92
    $this->container->get('plugin.manager.views.field')->getHandler($item);
93 94 95 96 97 98 99
    $this->assertTrue(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'views_test_data', '@field' => 'field_invalid', '@type' => 'field'))) !== FALSE, 'An invalid field name throws a debug message.');
    unset($this->lastErrorMessage);

    $item = array(
      'table' => 'table_invalid',
      'field' => 'id',
    );
100
    $this->container->get('plugin.manager.views.filter')->getHandler($item);
101 102 103 104 105 106 107
    $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'))) !== FALSE, 'An invalid table name throws a debug message.');
    unset($this->lastErrorMessage);

    $item = array(
      'table' => 'table_invalid',
      'field' => 'id',
    );
108
    $this->container->get('plugin.manager.views.filter')->getHandler($item);
109 110 111 112 113 114 115 116 117
    $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'))) !== FALSE, 'An invalid table name throws a debug message.');
    unset($this->lastErrorMessage);

    restore_error_handler();
  }

  /**
   * Defines an error handler which is used in the test.
   *
118 119
   * Because this is registered in set_error_handler(), it has to be public.
   *
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
   * @param int $error_level
   *   The level of the error raised.
   * @param string $message
   *   The error message.
   * @param string $filename
   *   The filename that the error was raised in.
   * @param int $line
   *   The line number the error was raised at.
   * @param array $context
   *   An array that points to the active symbol table at the point the error
   *   occurred.
   *
   * @see set_error_handler()
   */
  public function customErrorHandler($error_level, $message, $filename, $line, $context) {
    $this->lastErrorMessage = $message;
merlinofchaos's avatar
merlinofchaos committed
136 137
  }

138 139 140 141
  /**
   * Tests the load wrapper/helper functions.
   */
  public function testLoadFunctions() {
142
    $this->enableModules(array('text', 'node'));
143
    $this->installConfig(array('node'));
144
    $storage = $this->container->get('entity.manager')->getStorage('view');
145 146

    // Test views_view_is_enabled/disabled.
147
    $archive = $storage->load('archive');
148 149 150 151 152 153
    $this->assertTrue(views_view_is_disabled($archive), 'views_view_is_disabled works as expected.');
    // Enable the view and check this.
    $archive->enable();
    $this->assertTrue(views_view_is_enabled($archive), ' views_view_is_enabled works as expected.');

    // We can store this now, as we have enabled/disabled above.
154
    $all_views = $storage->loadMultiple();
155

156
    // Test Views::getAllViews().
157 158
    ksort($all_views);
    $this->assertEquals(array_keys($all_views), array_keys(Views::getAllViews()), 'Views::getAllViews works as expected.');
159

160
    // Test Views::getEnabledViews().
161 162 163
    $expected_enabled = array_filter($all_views, function($view) {
      return views_view_is_enabled($view);
    });
164
    $this->assertEquals(array_keys($expected_enabled), array_keys(Views::getEnabledViews()), 'Expected enabled views returned.');
165

166
    // Test Views::getDisabledViews().
167 168 169
    $expected_disabled = array_filter($all_views, function($view) {
      return views_view_is_disabled($view);
    });
170
    $this->assertEquals(array_keys($expected_disabled), array_keys(Views::getDisabledViews()), 'Expected disabled views returned.');
171

172
    // Test Views::getViewsAsOptions().
173
    // Test the $views_only parameter.
174
    $this->assertIdentical(array_keys($all_views), array_keys(Views::getViewsAsOptions(TRUE)), 'Expected option keys for all views were returned.');
175 176
    $expected_options = array();
    foreach ($all_views as $id => $view) {
177
      $expected_options[$id] = $view->label();
178
    }
179
    $this->assertIdentical($expected_options, $this->castSafeStrings(Views::getViewsAsOptions(TRUE)), 'Expected options array was returned.');
180 181

    // Test the default.
182
    $this->assertIdentical($this->formatViewOptions($all_views), $this->castSafeStrings(Views::getViewsAsOptions()), 'Expected options array for all views was returned.');
183
    // Test enabled views.
184
    $this->assertIdentical($this->formatViewOptions($expected_enabled), $this->castSafeStrings(Views::getViewsAsOptions(FALSE, 'enabled')), 'Expected enabled options array was returned.');
185
    // Test disabled views.
186
    $this->assertIdentical($this->formatViewOptions($expected_disabled), $this->castSafeStrings(Views::getViewsAsOptions(FALSE, 'disabled')), 'Expected disabled options array was returned.');
187 188 189 190

    // Test the sort parameter.
    $all_views_sorted = $all_views;
    ksort($all_views_sorted);
191
    $this->assertIdentical(array_keys($all_views_sorted), array_keys(Views::getViewsAsOptions(TRUE, 'all', NULL, FALSE, TRUE)), 'All view id keys returned in expected sort order');
192 193

    // Test $exclude_view parameter.
194 195 196
    $this->assertFalse(array_key_exists('archive', Views::getViewsAsOptions(TRUE, 'all', 'archive')), 'View excluded from options based on name');
    $this->assertFalse(array_key_exists('archive:default', Views::getViewsAsOptions(FALSE, 'all', 'archive:default')), 'View display excluded from options based on name');
    $this->assertFalse(array_key_exists('archive', Views::getViewsAsOptions(TRUE, 'all', $archive->getExecutable())), 'View excluded from options based on object');
197 198 199

    // Test the $opt_group parameter.
    $expected_opt_groups = array();
200 201
    foreach ($all_views as $view) {
      foreach ($view->get('display') as $display) {
202
        $expected_opt_groups[$view->id()][$view->id() . ':' . $display['id']] = (string) t('@view : @display', array('@view' => $view->id(), '@display' => $display['id']));
203 204
      }
    }
205
    $this->assertIdentical($expected_opt_groups, $this->castSafeStrings(Views::getViewsAsOptions(FALSE, 'all', NULL, TRUE)), 'Expected option array for an option group returned.');
206 207 208 209 210 211
  }

  /**
   * Tests view enable and disable procedural wrapper functions.
   */
  function testStatusFunctions() {
212
    $view = Views::getView('test_view_status')->storage;
213

214
    $this->assertFalse($view->status(), 'The view status is disabled.');
215 216

    views_enable_view($view);
217 218
    $this->assertTrue($view->status(), 'A view has been enabled.');
    $this->assertEqual($view->status(), views_view_is_enabled($view), 'views_view_is_enabled is correct.');
219 220

    views_disable_view($view);
221 222
    $this->assertFalse($view->status(), 'A view has been disabled.');
    $this->assertEqual(!$view->status(), views_view_is_disabled($view), 'views_view_is_disabled is correct.');
223 224
  }

225
  /**
226
   * Tests the \Drupal\views\Views::fetchPluginNames() method.
227 228 229
   */
  public function testViewsFetchPluginNames() {
    // All style plugins should be returned, as we have not specified a type.
230
    $plugins = Views::fetchPluginNames('style');
231
    $definitions = $this->container->get('plugin.manager.views.style')->getDefinitions();
232
    $expected = array();
233
    foreach ($definitions as $id => $definition) {
234 235 236 237 238 239 240
      $expected[$id] = $definition['title'];
    }
    asort($expected);
    $this->assertIdentical(array_keys($plugins), array_keys($expected));

    // Test using the 'test' style plugin type only returns the test_style and
    // mapping_test plugins.
241
    $plugins = Views::fetchPluginNames('style', 'test');
242
    $this->assertIdentical(array_keys($plugins), array('mapping_test', 'test_style', 'test_template_style'));
243 244

    // Test a non existent style plugin type returns no plugins.
245
    $plugins = Views::fetchPluginNames('style', $this->randomString());
246 247 248
    $this->assertIdentical($plugins, array());
  }

249
  /**
250
   * Tests the \Drupal\views\Views::pluginList() method.
251 252
   */
  public function testViewsPluginList() {
253
    $plugin_list = Views::pluginList();
254 255 256 257 258
    // Only plugins used by 'test_view' should be in the plugin list.
    foreach (array('display:default', 'pager:none') as $key) {
      list($plugin_type, $plugin_id) = explode(':', $key);
      $plugin_def = $this->container->get("plugin.manager.views.$plugin_type")->getDefinition($plugin_id);

259
      $this->assertTrue(isset($plugin_list[$key]), SafeMarkup::format('The expected @key plugin list key was found.', array('@key' => $key)));
260 261 262 263 264 265 266 267 268
      $plugin_details = $plugin_list[$key];

      $this->assertEqual($plugin_details['type'], $plugin_type, 'The expected plugin type was found.');
      $this->assertEqual($plugin_details['title'], $plugin_def['title'], 'The expected plugin title was found.');
      $this->assertEqual($plugin_details['provider'], $plugin_def['provider'], 'The expected plugin provider was found.');
      $this->assertTrue(in_array('test_view', $plugin_details['views']), 'The test_view View was found in the list of views using this plugin.');
    }
  }

269 270 271 272
  /**
   * Tests views.module: views_embed_view().
   */
  public function testViewsEmbedView() {
273 274 275
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = \Drupal::service('renderer');

276
    $result = views_embed_view('test_argument');
277 278
    $renderer->renderPlain($result);
    $this->assertEqual(count($result['view_build']['#view']->result), 5);
279 280

    $result = views_embed_view('test_argument', 'default', 1);
281 282
    $renderer->renderPlain($result);
    $this->assertEqual(count($result['view_build']['#view']->result), 1);
283 284

    $result = views_embed_view('test_argument', 'default', '1,2');
285 286
    $renderer->renderPlain($result);
    $this->assertEqual(count($result['view_build']['#view']->result), 2);
287 288

    $result = views_embed_view('test_argument', 'default', '1,2', 'John');
289 290
    $renderer->renderPlain($result);
    $this->assertEqual(count($result['view_build']['#view']->result), 1);
291 292

    $result = views_embed_view('test_argument', 'default', '1,2', 'John,George');
293 294
    $renderer->renderPlain($result);
    $this->assertEqual(count($result['view_build']['#view']->result), 2);
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
  }

  /**
   * Tests the \Drupal\views\ViewsExecutable::preview() method.
   */
  public function testViewsPreview() {
    $view = Views::getView('test_argument');
    $result = $view->preview('default');
    $this->assertEqual(count($result['#view']->result), 5);

    $view = Views::getView('test_argument');
    $result = $view->preview('default', array('0' => 1));
    $this->assertEqual(count($result['#view']->result), 1);

    $view = Views::getView('test_argument');
    $result = $view->preview('default', array('3' => 1));
    $this->assertEqual(count($result['#view']->result), 1);

    $view = Views::getView('test_argument');
    $result = $view->preview('default', array('0' => '1,2'));
    $this->assertEqual(count($result['#view']->result), 2);

    $view = Views::getView('test_argument');
    $result = $view->preview('default', array('3' => '1,2'));
    $this->assertEqual(count($result['#view']->result), 2);

    $view = Views::getView('test_argument');
    $result = $view->preview('default', array('0' => '1,2', '1' => 'John'));
    $this->assertEqual(count($result['#view']->result), 1);

    $view = Views::getView('test_argument');
    $result = $view->preview('default', array('3' => '1,2', '4' => 'John'));
    $this->assertEqual(count($result['#view']->result), 1);

    $view = Views::getView('test_argument');
    $result = $view->preview('default', array('0' => '1,2', '1' => 'John,George'));
    $this->assertEqual(count($result['#view']->result), 2);

    $view = Views::getView('test_argument');
    $result = $view->preview('default', array('3' => '1,2', '4' => 'John,George'));
    $this->assertEqual(count($result['#view']->result), 2);
  }

338 339 340 341
  /**
   * Helper to return an expected views option array.
   *
   * @param array $views
342
   *   An array of Drupal\views\Entity\View objects for which to
343
   *   create an options array.
344 345 346 347 348 349
   *
   * @return array
   *   A formatted options array that matches the expected output.
   */
  protected function formatViewOptions(array $views = array()) {
    $expected_options = array();
350 351
    foreach ($views as $view) {
      foreach ($view->get('display') as $display) {
352
        $expected_options[$view->id() . ':' . $display['id']] = (string) t('View: @view - Display: @display',
353
          array('@view' => $view->id(), '@display' => $display['id']));
354 355 356 357 358 359
      }
    }

    return $expected_options;
  }

merlinofchaos's avatar
merlinofchaos committed
360 361 362 363
  /**
   * Ensure that a certain handler is a instance of a certain table/field.
   */
  function assertInstanceHandler($handler, $table, $field, $id) {
364
    $table_data = $this->container->get('views.views_data')->get($table);
merlinofchaos's avatar
merlinofchaos committed
365 366
    $field_data = $table_data[$field][$id];

aspilicious's avatar
aspilicious committed
367
    $this->assertEqual($field_data['id'], $handler->getPluginId());
merlinofchaos's avatar
merlinofchaos committed
368
  }
369

merlinofchaos's avatar
merlinofchaos committed
370
}