Update to Drupal 8.0.0-beta15. For more information, see: https://www.drupal.org/node/2563023
This commit is contained in:
parent
2720a9ec4b
commit
f3791f1da3
1898 changed files with 54300 additions and 11481 deletions
|
@ -36,3 +36,6 @@ views.argument_validator_entity:
|
|||
multiple:
|
||||
type: integer
|
||||
label: 'Multiple arguments'
|
||||
|
||||
views.argument_validator.entity:*:
|
||||
type: views.argument_validator_entity
|
||||
|
|
|
@ -41,10 +41,6 @@ views.sort_expose.date:
|
|||
views.sort_expose.standard:
|
||||
type: views_sort_expose
|
||||
label: 'Standard sort expose settings'
|
||||
mapping:
|
||||
order:
|
||||
type: string
|
||||
label: 'Order'
|
||||
|
||||
views.sort_expose.random:
|
||||
type: views.sort_expose.standard
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Attaches the AJAX behavior to Views exposed filter forms and key View
|
||||
* links.
|
||||
* Attaches the AJAX behavior to exposed filters forms and key View links.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches ajaxView functionality to relevant elements.
|
||||
*/
|
||||
Drupal.behaviors.ViewsAjaxView = {};
|
||||
Drupal.behaviors.ViewsAjaxView.attach = function () {
|
||||
|
@ -41,7 +43,9 @@
|
|||
* @constructor
|
||||
*
|
||||
* @param {object} settings
|
||||
* Settings object for the ajax view.
|
||||
* @param {string} settings.view_dom_id
|
||||
* The DOM id of the view.
|
||||
*/
|
||||
Drupal.views.ajaxView = function (settings) {
|
||||
var selector = '.js-view-dom-id-' + settings.view_dom_id;
|
||||
|
@ -142,8 +146,10 @@
|
|||
/**
|
||||
* Attach the ajax behavior to a singe link.
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {string} [id]
|
||||
* The ID of the link.
|
||||
* @param {HTMLElement} link
|
||||
* The link element.
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function (id, link) {
|
||||
var $link = $(link);
|
||||
|
@ -168,10 +174,14 @@
|
|||
};
|
||||
|
||||
/**
|
||||
* Views scroll to top ajax command.
|
||||
*
|
||||
* @param {Drupal.Ajax} [ajax]
|
||||
* A {@link Drupal.ajax} object.
|
||||
* @param {object} response
|
||||
* Ajax response.
|
||||
* @param {string} response.selector
|
||||
* Selector to use.
|
||||
*/
|
||||
Drupal.AjaxCommands.prototype.viewsScrollTop = function (ajax, response) {
|
||||
// Scroll to the top of the view. This will allow users
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
* Helper function to parse a querystring.
|
||||
*
|
||||
* @param {string} query
|
||||
* The querystring to parse.
|
||||
*
|
||||
* @return {object}
|
||||
* A map of query parameters.
|
||||
*/
|
||||
Drupal.Views.parseQueryString = function (query) {
|
||||
var args = {};
|
||||
|
@ -41,9 +43,12 @@
|
|||
* Helper function to return a view's arguments based on a path.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to check.
|
||||
* @param {string} viewPath
|
||||
* The views path to check.
|
||||
*
|
||||
* @return {object}
|
||||
* An object containing `view_args` and `view_path`.
|
||||
*/
|
||||
Drupal.Views.parseViewArgs = function (href, viewPath) {
|
||||
var returnObj = {};
|
||||
|
@ -61,8 +66,10 @@
|
|||
* Strip off the protocol plus domain from an href.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to strip.
|
||||
*
|
||||
* @return {string}
|
||||
* The href without the protocol and domain.
|
||||
*/
|
||||
Drupal.Views.pathPortion = function (href) {
|
||||
// Remove e.g. http://example.com if present.
|
||||
|
@ -78,8 +85,10 @@
|
|||
* Return the Drupal path portion of an href.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to check.
|
||||
*
|
||||
* @return {string}
|
||||
* An internal path.
|
||||
*/
|
||||
Drupal.Views.getPath = function (href) {
|
||||
href = Drupal.Views.pathPortion(href);
|
||||
|
|
|
@ -8,8 +8,12 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Attaches contextual region classes to views elements.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Adds class `contextual-region` to views elements.
|
||||
*/
|
||||
Drupal.behaviors.viewsContextualLinks = {
|
||||
attach: function (context) {
|
||||
|
|
|
@ -38,6 +38,12 @@ class View extends RenderElement {
|
|||
* View element pre render callback.
|
||||
*/
|
||||
public static function preRenderViewElement($element) {
|
||||
// Allow specific Views displays to explicitly perform pre-rendering, for
|
||||
// those displays that need to be able to know the fully built render array.
|
||||
if (!empty($element['#pre_rendered'])) {
|
||||
return $element;
|
||||
}
|
||||
|
||||
if (!isset($element['#view'])) {
|
||||
$view = Views::getView($element['#name']);
|
||||
}
|
||||
|
@ -58,7 +64,7 @@ class View extends RenderElement {
|
|||
|
||||
if ($view && $view->access($element['#display_id'])) {
|
||||
if (!empty($element['#embed'])) {
|
||||
$element += $view->preview($element['#display_id'], $element['#arguments']);
|
||||
$element['view_build'] = $view->preview($element['#display_id'], $element['#arguments']);
|
||||
}
|
||||
else {
|
||||
// Add contextual links to the view. We need to attach them to the dummy
|
||||
|
|
|
@ -16,7 +16,7 @@ use Drupal\views\ResultRow;
|
|||
abstract class EntityTranslationRendererBase extends RendererBase {
|
||||
|
||||
/**
|
||||
* Returns the language code associated to the given row.
|
||||
* Returns the language code associated with the given row.
|
||||
*
|
||||
* @param \Drupal\views\ResultRow $row
|
||||
* The result row.
|
||||
|
|
|
@ -353,7 +353,7 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac
|
|||
case 'timestamp':
|
||||
case 'created':
|
||||
case 'changed':
|
||||
$views_field['field']['id'] = 'date';
|
||||
$views_field['field']['id'] = 'field';
|
||||
$views_field['argument']['id'] = 'date';
|
||||
$views_field['filter']['id'] = 'date';
|
||||
$views_field['sort']['id'] = 'date';
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
namespace Drupal\views\Plugin\Block;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Config\Entity\Query\Query;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Element\View;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -33,13 +33,26 @@ class ViewsBlock extends ViewsBlockBase {
|
|||
if ($output = $this->view->buildRenderable($this->displayID, [], FALSE)) {
|
||||
// Override the label to the dynamic title configured in the view.
|
||||
if (empty($this->configuration['views_label']) && $this->view->getTitle()) {
|
||||
// @todo https://www.drupal.org/node/2527360 remove call to SafeMarkup.
|
||||
$output['#title'] = SafeMarkup::xssFilter($this->view->getTitle(), Xss::getAdminTagList());
|
||||
$output['#title'] = ['#markup' => $this->view->getTitle(), '#allowed_tags' => Xss::getHtmlTagList()];
|
||||
}
|
||||
|
||||
// Before returning the block output, convert it to a renderable array
|
||||
// with contextual links.
|
||||
$this->addContextualLinks($output);
|
||||
|
||||
// Block module expects to get a final render array, without another
|
||||
// top-level #pre_render callback. So, here we make sure that Views'
|
||||
// #pre_render callback has already been applied.
|
||||
$output = View::preRenderViewElement($output);
|
||||
|
||||
// When view_build is empty, the actual render array output for this View
|
||||
// is going to be empty. In that case, return just #cache, so that the
|
||||
// render system knows the reasons (cache contexts & tags) why this Views
|
||||
// block is empty, and can cache it accordingly.
|
||||
if (empty($output['view_build'])) {
|
||||
$output = ['#cache' => $output['#cache']];
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,17 +7,10 @@
|
|||
|
||||
namespace Drupal\views\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\views\Views;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'selection' entity_reference.
|
||||
|
@ -29,28 +22,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
* weight = 0
|
||||
* )
|
||||
*/
|
||||
class ViewsSelection extends PluginBase implements SelectionInterface, ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
class ViewsSelection extends SelectionBase {
|
||||
|
||||
/**
|
||||
* The loaded View object.
|
||||
|
@ -59,44 +31,6 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* Constructs a new ViewsSelection object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager service.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler service.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->currentUser = $current_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -161,16 +95,6 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* Initializes a view.
|
||||
*
|
||||
|
@ -227,7 +151,7 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
|
||||
$return = array();
|
||||
if ($result) {
|
||||
foreach($this->view->result as $row) {
|
||||
foreach ($this->view->result as $row) {
|
||||
$entity = $row->_entity;
|
||||
$return[$entity->bundle()][$entity->id()] = $entity->label();
|
||||
}
|
||||
|
@ -259,18 +183,6 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateAutocompleteInput($input, &$element, FormStateInterface $form_state, $form, $strict = TRUE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) {}
|
||||
|
||||
/**
|
||||
* Element validate; Check View is valid.
|
||||
*/
|
||||
|
@ -300,4 +212,11 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
|||
$form_state->setValueForElement($element, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
throw new \BadMethodCallException('The Views selection plugin does not use the Entity Query system for entity selection.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -365,6 +365,12 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
|
|||
if (strpos($token, '{{') !== FALSE) {
|
||||
// Twig wants a token replacement array stripped of curly-brackets.
|
||||
$token = trim(str_replace(array('{', '}'), '', $token));
|
||||
|
||||
// We need to validate tokens are valid Twig variables. Twig uses the
|
||||
// same variable naming rules as PHP.
|
||||
// @see http://php.net/manual/en/language.variables.basics.php
|
||||
assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/\', $token) === 1', 'Tokens need to be valid Twig variables.');
|
||||
|
||||
$twig_tokens[$token] = $replacement;
|
||||
}
|
||||
else {
|
||||
|
@ -580,7 +586,7 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
|
|||
|
||||
// Add real languages.
|
||||
foreach ($languages as $id => $language) {
|
||||
$list[$id] = $this->t($language->getName());
|
||||
$list[$id] = $language->getName();
|
||||
}
|
||||
|
||||
return $list;
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\views\Plugin\views\argument;
|
|||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Field\AllowedTagsXssTrait;
|
||||
use Drupal\Core\Field\FieldFilteredString;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
|
@ -70,7 +71,7 @@ class FieldList extends NumericArgument {
|
|||
$value = $data->{$this->name_alias};
|
||||
// If the list element has a human readable name show it,
|
||||
if (isset($this->allowed_values[$value]) && !empty($this->options['summary']['human'])) {
|
||||
return $this->fieldFilterXss($this->allowed_values[$value]);
|
||||
return FieldFilteredString::create($this->allowed_values[$value]);
|
||||
}
|
||||
// else fallback to the key.
|
||||
else {
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\views\Plugin\views\argument;
|
|||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Field\AllowedTagsXssTrait;
|
||||
use Drupal\Core\Field\FieldFilteredString;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
|
@ -72,12 +73,9 @@ class ListString extends StringArgument {
|
|||
$value = $data->{$this->name_alias};
|
||||
// If the list element has a human readable name show it,
|
||||
if (isset($this->allowed_values[$value]) && !empty($this->options['summary']['human'])) {
|
||||
return $this->caseTransform($this->fieldfilterXss($this->allowed_values[$value]), $this->options['case']);
|
||||
}
|
||||
// else fallback to the key.
|
||||
else {
|
||||
return $this->caseTransform(SafeMarkup::checkPlain($value), $this->options['case']);
|
||||
$value = $this->allowed_values[$value];
|
||||
}
|
||||
return FieldFilteredString::create($this->caseTransform($value, $this->options['case']));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ class StringArgument extends ArgumentPluginBase {
|
|||
* Override for specific title lookups.
|
||||
*/
|
||||
public function titleQuery() {
|
||||
return array_map('\Drupal\Component\Utility\SafeMarkup::checkPlain', array_combine($this->value, $this->value));
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function summaryName($data) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\views\Plugin\views\display;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Plugin\Block\ViewsBlock;
|
||||
|
@ -149,7 +148,7 @@ class Block extends DisplayPluginBase {
|
|||
if (empty($block_description)) {
|
||||
$block_description = $this->t('None');
|
||||
}
|
||||
$block_category = SafeMarkup::checkPlain($this->getOption('block_category'));
|
||||
$block_category = $this->getOption('block_category');
|
||||
|
||||
$options['block_description'] = array(
|
||||
'category' => 'block',
|
||||
|
|
|
@ -1062,7 +1062,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
|||
}
|
||||
// Use strip tags as there should never be HTML in the path.
|
||||
// However, we need to preserve special characters like " that
|
||||
// were removed by SafeMarkup::checkPlain().
|
||||
// were encoded by \Drupal\Component\Utility\Html::escape().
|
||||
$tokens["!$count"] = isset($this->view->args[$count - 1]) ? strip_tags(Html::decodeEntities($this->view->args[$count - 1])) : '';
|
||||
}
|
||||
|
||||
|
@ -1394,7 +1394,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
|||
if ($this->defaultableSections($section)) {
|
||||
views_ui_standard_display_dropdown($form, $form_state, $section);
|
||||
}
|
||||
$form['#title'] = SafeMarkup::checkPlain($this->display['display_title']) . ': ';
|
||||
$form['#title'] = $this->display['display_title'] . ': ';
|
||||
|
||||
// Set the 'section' to highlight on the form.
|
||||
// If it's the item we're looking at is pulling from the default display,
|
||||
|
|
|
@ -99,7 +99,7 @@ class Feed extends PathPluginBase implements ResponseDisplayPluginInterface {
|
|||
if (!empty($this->view->live_preview)) {
|
||||
$output = array(
|
||||
'#prefix' => '<pre>',
|
||||
'#markup' => SafeMarkup::checkPlain(drupal_render_root($output)),
|
||||
'#plain_text' => drupal_render_root($output),
|
||||
'#suffix' => '</pre>',
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\views\Plugin\views\display;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
@ -182,8 +181,7 @@ class Page extends PathPluginBase {
|
|||
// it should be dropped.
|
||||
if (is_array($render)) {
|
||||
$render += array(
|
||||
// @todo https://www.drupal.org/node/2527360 remove call to SafeMarkup.
|
||||
'#title' => SafeMarkup::xssFilter($this->view->getTitle(), Xss::getAdminTagList()),
|
||||
'#title' => ['#markup' => $this->view->getTitle(), '#allowed_tags' => Xss::getHtmlTagList()],
|
||||
);
|
||||
}
|
||||
return $render;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Plugin\views\field;
|
||||
|
||||
use Drupal\Component\Utility\Xss as CoreXss;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
|
@ -670,7 +670,7 @@ class Field extends FieldPluginBase implements CacheablePluginInterface, MultiIt
|
|||
if (!empty($items)) {
|
||||
$items = $this->prepareItemsByDelta($items);
|
||||
if ($this->options['multi_type'] == 'separator' || !$this->options['group_rows']) {
|
||||
$separator = $this->options['multi_type'] == 'separator' ? CoreXss::filterAdmin($this->options['separator']) : '';
|
||||
$separator = $this->options['multi_type'] == 'separator' ? Xss::filterAdmin($this->options['separator']) : '';
|
||||
$build = [
|
||||
'#type' => 'inline_template',
|
||||
'#template' => '{{ items | safe_join(separator) }}',
|
||||
|
@ -903,7 +903,7 @@ class Field extends FieldPluginBase implements CacheablePluginInterface, MultiIt
|
|||
protected function documentSelfTokens(&$tokens) {
|
||||
$field = $this->getFieldDefinition();
|
||||
foreach ($field->getColumns() as $id => $column) {
|
||||
$tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = $this->t('Raw @column', array('@column' => $id));
|
||||
$tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = $this->t('Raw @column', array('@column' => $id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,19 +913,29 @@ class Field extends FieldPluginBase implements CacheablePluginInterface, MultiIt
|
|||
// Use \Drupal\Component\Utility\Xss::filterAdmin() because it's user data
|
||||
// and we can't be sure it is safe. We know nothing about the data,
|
||||
// though, so we can't really do much else.
|
||||
|
||||
if (isset($item['raw'])) {
|
||||
// If $item['raw'] is an array then we can use as is, if it's an object
|
||||
// we cast it to an array, if it's neither, we can't use it.
|
||||
$raw = is_array($item['raw']) ? $item['raw'] :
|
||||
(is_object($item['raw']) ? (array)$item['raw'] : NULL);
|
||||
}
|
||||
if (isset($raw) && isset($raw[$id]) && is_scalar($raw[$id])) {
|
||||
$tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = CoreXss::filterAdmin($raw[$id]);
|
||||
}
|
||||
else {
|
||||
// Make sure that empty values are replaced as well.
|
||||
$tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = '';
|
||||
$raw = $item['raw'];
|
||||
|
||||
if (is_array($raw)) {
|
||||
if (isset($raw[$id]) && is_scalar($raw[$id])) {
|
||||
$tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($raw[$id]);
|
||||
}
|
||||
else {
|
||||
// Make sure that empty values are replaced as well.
|
||||
$tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (is_object($raw)) {
|
||||
$property = $raw->get($id);
|
||||
if (!empty($property)) {
|
||||
$tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getValue());
|
||||
}
|
||||
else {
|
||||
// Make sure that empty values are replaced as well.
|
||||
$tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,8 +167,10 @@ interface FieldHandlerInterface extends ViewsHandlerInterface {
|
|||
* @param \Drupal\views\ResultRow $values
|
||||
* The values retrieved from a single row of a view's query result.
|
||||
*
|
||||
* @return string
|
||||
* The rendered output.
|
||||
* @return string|\Drupal\Component\Utility\SafeStringInterface
|
||||
* The rendered output. If the output is safe it will be wrapped in an
|
||||
* object that implements SafeStringInterface. If it is empty or unsafe it
|
||||
* will be a string.
|
||||
*
|
||||
*/
|
||||
public function render(ResultRow $values);
|
||||
|
@ -202,8 +204,10 @@ interface FieldHandlerInterface extends ViewsHandlerInterface {
|
|||
* @param \Drupal\views\ResultRow $values
|
||||
* The values retrieved from a single row of a view's query result.
|
||||
*
|
||||
* @return string
|
||||
* The advanced rendered output.
|
||||
* @return string|\Drupal\Component\Utility\SafeStringInterface
|
||||
* The advanced rendered output. If the output is safe it will be wrapped in
|
||||
* an object that implements SafeStringInterface. If it is empty or unsafe
|
||||
* it will be a string.
|
||||
*
|
||||
*/
|
||||
public function advancedRender(ResultRow $values);
|
||||
|
@ -236,29 +240,13 @@ interface FieldHandlerInterface extends ViewsHandlerInterface {
|
|||
* - ellipsis: Show an ellipsis (…) at the end of the trimmed string.
|
||||
* - html: Make sure that the html is correct.
|
||||
*
|
||||
* @return string
|
||||
* The rendered string.
|
||||
* @return string|\Drupal\Component\Utility\SafeStringInterface
|
||||
* The rendered output. If the output is safe it will be wrapped in an
|
||||
* object that implements SafeStringInterface. If it is empty or unsafe it
|
||||
* will be a string.
|
||||
*/
|
||||
public function renderText($alter);
|
||||
|
||||
/**
|
||||
* Trims the field down to the specified length.
|
||||
*
|
||||
* @param array $alter
|
||||
* The alter array of options to use.
|
||||
* - max_length: Maximum length of the string, the rest gets truncated.
|
||||
* - word_boundary: Trim only on a word boundary.
|
||||
* - ellipsis: Show an ellipsis (…) at the end of the trimmed string.
|
||||
* - html: Make sure that the html is correct.
|
||||
*
|
||||
* @param string $value
|
||||
* The string which should be trimmed.
|
||||
*
|
||||
* @return string
|
||||
* The rendered trimmed string.
|
||||
*/
|
||||
public function renderTrimText($alter, $value);
|
||||
|
||||
/**
|
||||
* Gets the 'render' tokens to use for advanced rendering.
|
||||
*
|
||||
|
@ -280,8 +268,10 @@ interface FieldHandlerInterface extends ViewsHandlerInterface {
|
|||
* @param \Drupal\views\ResultRow $values
|
||||
* Holds single row of a view's result set.
|
||||
*
|
||||
* @return string|false
|
||||
* Returns rendered output of the given theme implementation.
|
||||
* @return string|\Drupal\Component\Utility\SafeStringInterface
|
||||
* Returns rendered output of the given theme implementation. If the output
|
||||
* is safe it will be wrapped in an object that implements
|
||||
* SafeStringInterface. If it is empty or unsafe it will be a string.
|
||||
*/
|
||||
function theme(ResultRow $values);
|
||||
|
||||
|
|
|
@ -10,16 +10,17 @@ namespace Drupal\views\Plugin\views\field;
|
|||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\SafeStringInterface;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Renderer;
|
||||
use Drupal\Core\Render\SafeString;
|
||||
use Drupal\Core\Url as CoreUrl;
|
||||
use Drupal\views\Plugin\views\HandlerBase;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\Render\ViewsRenderPipelineSafeString;
|
||||
use Drupal\views\ResultRow;
|
||||
use Drupal\views\ViewExecutable;
|
||||
|
||||
|
@ -241,7 +242,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
}
|
||||
}
|
||||
if ($this->options['element_type']) {
|
||||
return SafeMarkup::checkPlain($this->options['element_type']);
|
||||
return $this->options['element_type'];
|
||||
}
|
||||
|
||||
if ($default_empty) {
|
||||
|
@ -269,7 +270,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
}
|
||||
}
|
||||
if ($this->options['element_label_type']) {
|
||||
return SafeMarkup::checkPlain($this->options['element_label_type']);
|
||||
return $this->options['element_label_type'];
|
||||
}
|
||||
|
||||
if ($default_empty) {
|
||||
|
@ -289,7 +290,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
}
|
||||
}
|
||||
if ($this->options['element_wrapper_type']) {
|
||||
return SafeMarkup::checkPlain($this->options['element_wrapper_type']);
|
||||
return $this->options['element_wrapper_type'];
|
||||
}
|
||||
|
||||
if ($default_empty) {
|
||||
|
@ -1138,7 +1139,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
else {
|
||||
$value = $this->render($values);
|
||||
if (is_array($value)) {
|
||||
$value = (string) $this->getRenderer()->render($value);
|
||||
$value = $this->getRenderer()->render($value);
|
||||
}
|
||||
$this->last_render = $value;
|
||||
$this->original_value = $value;
|
||||
|
@ -1169,14 +1170,16 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$value = (string) $this->getRenderer()->render($value);
|
||||
$value = $this->getRenderer()->render($value);
|
||||
}
|
||||
// This happens here so that renderAsLink can get the unaltered value of
|
||||
// this field as a token rather than the altered value.
|
||||
$this->last_render = $value;
|
||||
}
|
||||
|
||||
if (empty($this->last_render)) {
|
||||
// String cast is necessary to test emptiness of SafeStringInterface
|
||||
// objects.
|
||||
if (empty((string) $this->last_render)) {
|
||||
if ($this->isValueEmpty($this->last_render, $this->options['empty_zero'], FALSE)) {
|
||||
$alter = $this->options['alter'];
|
||||
$alter['alter_text'] = 1;
|
||||
|
@ -1185,9 +1188,6 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
$this->last_render = $this->renderText($alter);
|
||||
}
|
||||
}
|
||||
// @todo Fix this in https://www.drupal.org/node/2280961.
|
||||
$this->last_render = SafeMarkup::set($this->last_render);
|
||||
|
||||
|
||||
return $this->last_render;
|
||||
}
|
||||
|
@ -1196,6 +1196,10 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function isValueEmpty($value, $empty_zero, $no_skip_empty = TRUE) {
|
||||
// Convert SafeStringInterface to a string for checking.
|
||||
if ($value instanceof SafeStringInterface) {
|
||||
$value = (string) $value;
|
||||
}
|
||||
if (!isset($value)) {
|
||||
$empty = TRUE;
|
||||
}
|
||||
|
@ -1213,7 +1217,14 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderText($alter) {
|
||||
$value = $this->last_render;
|
||||
// We need to preserve the safeness of the value regardless of the
|
||||
// alterations made by this method. Any alterations or replacements made
|
||||
// within this method need to ensure that at the minimum the result is
|
||||
// XSS admin filtered. See self::renderAltered() as an example that does.
|
||||
$value_is_safe = SafeMarkup::isSafe($this->last_render);
|
||||
// Cast to a string so that empty checks and string functions work as
|
||||
// expected.
|
||||
$value = (string) $this->last_render;
|
||||
|
||||
if (!empty($alter['alter_text']) && $alter['text'] !== '') {
|
||||
$tokens = $this->getRenderTokens($alter);
|
||||
|
@ -1239,6 +1250,9 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
if ($alter['phase'] == static::RENDER_TEXT_PHASE_EMPTY && $no_rewrite_for_empty) {
|
||||
// If we got here then $alter contains the value of "No results text"
|
||||
// and so there is nothing left to do.
|
||||
if ($value_is_safe) {
|
||||
$value = ViewsRenderPipelineSafeString::create($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
@ -1275,6 +1289,12 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
if (!empty($alter['nl2br'])) {
|
||||
$value = nl2br($value);
|
||||
}
|
||||
|
||||
// Preserve whether or not the string is safe. Since $suffix comes from
|
||||
// \Drupal::l(), it is safe to append.
|
||||
if ($value_is_safe) {
|
||||
$value = ViewsRenderPipelineSafeString::create($value . $suffix);
|
||||
}
|
||||
$this->last_render_text = $value;
|
||||
|
||||
if (!empty($alter['make_link']) && (!empty($alter['path']) || !empty($alter['url']))) {
|
||||
|
@ -1284,20 +1304,42 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
$value = $this->renderAsLink($alter, $value, $tokens);
|
||||
}
|
||||
|
||||
return $value . $suffix;
|
||||
// Preserve whether or not the string is safe. Since $suffix comes from
|
||||
// \Drupal::l(), it is safe to append.
|
||||
if ($value_is_safe) {
|
||||
return ViewsRenderPipelineSafeString::create($value . $suffix);
|
||||
}
|
||||
else {
|
||||
// If the string is not already marked safe, it is still OK to return it
|
||||
// because it will be sanitized by Twig.
|
||||
return $value . $suffix;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render this field as user-defined altered text.
|
||||
*/
|
||||
protected function renderAltered($alter, $tokens) {
|
||||
return SafeString::create($this->viewsTokenReplace($alter['text'], $tokens));
|
||||
return $this->viewsTokenReplace($alter['text'], $tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Trims the field down to the specified length.
|
||||
*
|
||||
* @param array $alter
|
||||
* The alter array of options to use.
|
||||
* - max_length: Maximum length of the string, the rest gets truncated.
|
||||
* - word_boundary: Trim only on a word boundary.
|
||||
* - ellipsis: Show an ellipsis (…) at the end of the trimmed string.
|
||||
* - html: Make sure that the html is correct.
|
||||
*
|
||||
* @param string $value
|
||||
* The string which should be trimmed.
|
||||
*
|
||||
* @return string
|
||||
* The rendered trimmed string.
|
||||
*/
|
||||
public function renderTrimText($alter, $value) {
|
||||
protected function renderTrimText($alter, $value) {
|
||||
if (!empty($alter['strip_tags'])) {
|
||||
// NOTE: It's possible that some external fields might override the
|
||||
// element type.
|
||||
|
@ -1634,10 +1676,11 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
* fields as a list. For example, the field that displays all terms
|
||||
* on a node might have tokens for the tid and the term.
|
||||
*
|
||||
* By convention, tokens should follow the format of {{ token-subtoken }}
|
||||
* By convention, tokens should follow the format of {{ token
|
||||
* subtoken }}
|
||||
* where token is the field ID and subtoken is the field. If the
|
||||
* field ID is terms, then the tokens might be {{ terms-tid }} and
|
||||
* {{ terms-name }}.
|
||||
* field ID is terms, then the tokens might be {{ terms__tid }} and
|
||||
* {{ terms__name }}.
|
||||
*/
|
||||
protected function addSelfTokens(&$tokens, $item) { }
|
||||
|
||||
|
|
|
@ -766,7 +766,7 @@ abstract class FilterPluginBase extends HandlerBase implements CacheablePluginIn
|
|||
$value = $this->options['group_info']['identifier'];
|
||||
|
||||
$form[$value] = array(
|
||||
'#title' => SafeMarkup::checkPlain($this->options['group_info']['label']),
|
||||
'#title' => $this->options['group_info']['label'],
|
||||
'#type' => $this->options['group_info']['widget'],
|
||||
'#default_value' => $this->group_info,
|
||||
'#options' => $groups,
|
||||
|
|
|
@ -1454,7 +1454,7 @@ class Sql extends QueryPluginBase {
|
|||
drupal_set_message($e->getMessage(), 'error');
|
||||
}
|
||||
else {
|
||||
throw new DatabaseExceptionWrapper("Exception in {$view->storage->label()}[$view->storage->id()]: {$e->getMessage()}");
|
||||
throw new DatabaseExceptionWrapper("Exception in {$view->storage->label()}[{$view->storage->id()}]: {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -220,7 +220,6 @@ abstract class SortPluginBase extends HandlerBase implements CacheablePluginInte
|
|||
*/
|
||||
public function defaultExposeOptions() {
|
||||
$this->options['expose'] = array(
|
||||
'order' => $this->options['order'],
|
||||
'label' => $this->definition['title'],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,8 @@ abstract class Mapping extends StylePluginBase {
|
|||
// Optionally filter the available fields.
|
||||
if (isset($mapping[$key]['#filter'])) {
|
||||
$this->view->initHandlers();
|
||||
$this::$mapping[$key]['#filter']($field_options);
|
||||
$filter = $mapping[$key]['#filter'];
|
||||
$this::$filter($field_options);
|
||||
unset($mapping[$key]['#filter']);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@ use Drupal\Component\Utility\Html;
|
|||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\Core\Render\SafeString;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\Plugin\views\PluginBase;
|
||||
use Drupal\views\Plugin\views\wizard\WizardInterface;
|
||||
use Drupal\views\Render\ViewsRenderPipelineSafeString;
|
||||
use Drupal\views\ViewExecutable;
|
||||
|
||||
/**
|
||||
|
@ -708,7 +708,7 @@ abstract class StylePluginBase extends PluginBase {
|
|||
foreach ($this->rendered_fields[$index] as &$rendered_field) {
|
||||
// Placeholders and rendered fields have been processed by the
|
||||
// render system and are therefore safe.
|
||||
$rendered_field = SafeString::create(str_replace($placeholders, $values, $rendered_field));
|
||||
$rendered_field = ViewsRenderPipelineSafeString::create(str_replace($placeholders, $values, $rendered_field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -745,7 +745,7 @@ abstract class StylePluginBase extends PluginBase {
|
|||
* @param string $field
|
||||
* The ID of the field.
|
||||
*
|
||||
* @return \Drupal\Core\Render\SafeString|null
|
||||
* @return \Drupal\Component\Utility\SafeStringInterface|null
|
||||
* The output of the field, or NULL if it was empty.
|
||||
*/
|
||||
public function getField($index, $field) {
|
||||
|
|
|
@ -232,7 +232,7 @@ class Table extends StylePluginBase implements CacheablePluginInterface {
|
|||
$form['caption'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Caption for the table'),
|
||||
'#description' => $this->t('A title which is semantically associated to your table for increased accessibility.'),
|
||||
'#description' => $this->t('A title semantically associated with your table for increased accessibility.'),
|
||||
'#default_value' => $this->options['caption'],
|
||||
'#maxlength' => 255,
|
||||
);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Render\ViewsRenderPipelineSafeString.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Render;
|
||||
|
||||
use Drupal\Component\Utility\SafeStringInterface;
|
||||
use Drupal\Component\Utility\SafeStringTrait;
|
||||
|
||||
/**
|
||||
* Defines an object that passes safe strings through the Views render system.
|
||||
*
|
||||
* This object should only be constructed with a known safe string. If there is
|
||||
* any risk that the string contains user-entered data that has not been
|
||||
* filtered first, it must not be used.
|
||||
*
|
||||
* @internal
|
||||
* This object is marked as internal because it should only be used in the
|
||||
* Views render pipeline.
|
||||
*
|
||||
* @see \Drupal\Core\Render\SafeString
|
||||
*/
|
||||
final class ViewsRenderPipelineSafeString implements SafeStringInterface, \Countable {
|
||||
use SafeStringTrait;
|
||||
}
|
|
@ -14,7 +14,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class BasicTest extends ViewUnitTestBase {
|
||||
class BasicTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -57,7 +57,7 @@ class FieldEntityTest extends ViewTestBase {
|
|||
$account = entity_create('user', array('name' => $this->randomMachineName(), 'bundle' => 'user'));
|
||||
$account->save();
|
||||
|
||||
$node = entity_create('node', array('uid' => $account->id(), 'type' => 'page'));
|
||||
$node = entity_create('node', array('uid' => $account->id(), 'type' => 'page', 'title' => $this->randomString()));
|
||||
$node->save();
|
||||
$comment = entity_create('comment', array(
|
||||
'uid' => $account->id(),
|
||||
|
|
|
@ -60,7 +60,7 @@ class FilterEntityBundleTest extends ViewTestBase {
|
|||
|
||||
foreach ($this->entityBundles as $key => $info) {
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$entity = entity_create('node', array('label' => $this->randomMachineName(), 'uid' => 1, 'type' => $key));
|
||||
$entity = entity_create('node', array('title' => $this->randomString(), 'uid' => 1, 'type' => $key));
|
||||
$entity->save();
|
||||
$this->entities[$key][$entity->id()] = $entity;
|
||||
$this->entities['count']++;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\views\Tests\Entity;
|
|||
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Entity\Render\RendererBase
|
||||
*/
|
||||
class RowEntityRenderersTest extends ViewUnitTestBase {
|
||||
class RowEntityRenderersTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Drupal\views\Tests\Entity;
|
|||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class ViewEntityDependenciesTest extends ViewUnitTestBase {
|
||||
class ViewEntityDependenciesTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -11,14 +11,14 @@ use Drupal\Core\Entity\EntityTypeEvent;
|
|||
use Drupal\Core\Entity\EntityTypeEvents;
|
||||
use Drupal\system\Tests\Entity\EntityDefinitionTestTrait;
|
||||
use Drupal\views\Entity\View;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests \Drupal\views\EventSubscriber\ViewsEntitySchemaSubscriber
|
||||
*
|
||||
* @group Views
|
||||
*/
|
||||
class ViewsEntitySchemaSubscriberIntegrationTest extends ViewUnitTestBase {
|
||||
class ViewsEntitySchemaSubscriberIntegrationTest extends ViewKernelTestBase {
|
||||
|
||||
use EntityDefinitionTestTrait;
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ class GlossaryTest extends ViewTestBase {
|
|||
$this->assertPageCacheContextsAndTags(
|
||||
$url,
|
||||
[
|
||||
'timezone',
|
||||
'languages:' . LanguageInterface::TYPE_CONTENT,
|
||||
'languages:' . LanguageInterface::TYPE_INTERFACE,
|
||||
'theme',
|
||||
|
|
|
@ -11,7 +11,7 @@ use Drupal\block\Entity\Block;
|
|||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\views\Entity\View;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\area\Entity
|
||||
*/
|
||||
class AreaEntityTest extends ViewUnitTestBase {
|
||||
class AreaEntityTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
@ -128,8 +128,8 @@ class AreaEntityTest extends ViewUnitTestBase {
|
|||
$preview = $view->preview('default', [$entities[1]->id()]);
|
||||
$this->setRawContent(\Drupal::service('renderer')->renderRoot($preview));
|
||||
$view_class = 'js-view-dom-id-' . $view->dom_id;
|
||||
$header_xpath = '//div[@class = "' . $view_class . '"]/div[1]';
|
||||
$footer_xpath = '//div[@class = "' . $view_class . '"]/div[3]';
|
||||
$header_xpath = '//div[@class = "' . $view_class . '"]/header[1]';
|
||||
$footer_xpath = '//div[@class = "' . $view_class . '"]/footer[1]';
|
||||
|
||||
$result = $this->xpath($header_xpath);
|
||||
$this->assertTrue(strpos(trim((string) $result[0]), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.');
|
||||
|
@ -164,7 +164,7 @@ class AreaEntityTest extends ViewUnitTestBase {
|
|||
$preview = $view->preview('default', array($entities[1]->id()));
|
||||
$this->setRawContent($renderer->renderRoot($preview));
|
||||
$view_class = 'js-view-dom-id-' . $view->dom_id;
|
||||
$result = $this->xpath('//div[@class = "' . $view_class . '"]/div[1]');
|
||||
$result = $this->xpath('//div[@class = "' . $view_class . '"]/header[1]');
|
||||
$this->assertTrue(strpos(trim((string) $result[0]), $entities[0]->label()) !== FALSE, 'The rendered entity appears in the header of the view.');
|
||||
$this->assertTrue(strpos(trim((string) $result[0]), 'test') !== FALSE, 'The rendered entity appeared in the right view mode.');
|
||||
|
||||
|
@ -173,7 +173,7 @@ class AreaEntityTest extends ViewUnitTestBase {
|
|||
$preview = $view->preview('default', array($entities[2]->id()));
|
||||
$this->setRawContent($renderer->renderRoot($preview));
|
||||
$view_class = 'js-view-dom-id-' . $view->dom_id;
|
||||
$result = $this->xpath('//div[@class = "' . $view_class . '"]/div[3]');
|
||||
$result = $this->xpath('//div[@class = "' . $view_class . '"]/footer[1]');
|
||||
$this->assertTrue(strpos($result[0], $entities[2]->label()) === FALSE, 'The rendered entity does not appear in the footer of the view.');
|
||||
|
||||
// Test the available view mode options.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\area\Text
|
||||
*/
|
||||
class AreaTextTest extends ViewUnitTestBase {
|
||||
class AreaTextTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('system', 'user', 'filter');
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\area\Title
|
||||
*/
|
||||
class AreaTitleTest extends ViewUnitTestBase {
|
||||
class AreaTitleTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\area\View
|
||||
*/
|
||||
class AreaViewTest extends ViewUnitTestBase {
|
||||
class AreaViewTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\argument\Date
|
||||
*/
|
||||
class ArgumentDateTest extends ViewUnitTestBase {
|
||||
class ArgumentDateTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
@ -35,7 +35,7 @@ class ArgumentDateTest extends ViewUnitTestBase {
|
|||
);
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Tests\ViewUnitTestBase::viewsData().
|
||||
* Overrides \Drupal\views\Tests\ViewKernelTestBase::viewsData().
|
||||
*/
|
||||
public function viewsData() {
|
||||
$data = parent::viewsData();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class ArgumentNullTest extends ViewUnitTestBase {
|
||||
class ArgumentNullTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FieldBooleanTest extends ViewUnitTestBase {
|
||||
class FieldBooleanTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FieldCounterTest extends ViewUnitTestBase {
|
||||
class FieldCounterTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FieldCustomTest extends ViewUnitTestBase {
|
||||
class FieldCustomTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FieldDateTest extends ViewUnitTestBase {
|
||||
class FieldDateTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -10,7 +10,8 @@ namespace Drupal\views\Tests\Handler;
|
|||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\simpletest\UserCreationTrait;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +19,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FieldEntityLinkTest extends ViewUnitTestBase {
|
||||
class FieldEntityLinkTest extends ViewKernelTestBase {
|
||||
|
||||
use UserCreationTrait;
|
||||
|
||||
|
@ -51,6 +52,7 @@ class FieldEntityLinkTest extends ViewUnitTestBase {
|
|||
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('entity_test');
|
||||
$this->installConfig(['user']);
|
||||
|
||||
// Create some test entities.
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
|
@ -58,7 +60,11 @@ class FieldEntityLinkTest extends ViewUnitTestBase {
|
|||
}
|
||||
|
||||
// Create and admin user.
|
||||
$this->adminUser = $this->createUser([], FALSE, TRUE);
|
||||
$this->adminUser = $this->createUser(['view test entity'], FALSE, TRUE);
|
||||
|
||||
Role::load(AccountInterface::ANONYMOUS_ROLE)
|
||||
->grantPermission('view test entity')
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,13 +10,13 @@ namespace Drupal\views\Tests\Handler;
|
|||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\views\Entity\View;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Provides a base class for base field access in views.
|
||||
*/
|
||||
abstract class FieldFieldAccessTestBase extends ViewUnitTestBase {
|
||||
abstract class FieldFieldAccessTestBase extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Stores an user entity with access to fields.
|
||||
|
|
|
@ -14,7 +14,7 @@ use Drupal\field\Entity\FieldConfig;
|
|||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\views\Plugin\views\field\Field;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -23,7 +23,7 @@ use Drupal\views\Views;
|
|||
* @see \Drupal\views\Plugin\views\field\Field
|
||||
* @group views
|
||||
*/
|
||||
class FieldFieldTest extends ViewUnitTestBase {
|
||||
class FieldFieldTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -74,7 +74,7 @@ class FieldFieldTest extends ViewUnitTestBase {
|
|||
$this->installEntitySchema('entity_test_rev');
|
||||
|
||||
// Bypass any field access.
|
||||
$this->adminUser = User::create();
|
||||
$this->adminUser = User::create(['name' => $this->randomString()]);
|
||||
$this->adminUser->save();
|
||||
$this->container->get('current_user')->setAccount($this->adminUser);
|
||||
|
||||
|
@ -531,7 +531,7 @@ class FieldFieldTest extends ViewUnitTestBase {
|
|||
$executable = Views::getView('test_field_field_test');
|
||||
$executable->execute();
|
||||
|
||||
$this->assertEqual('', $executable->getStyle()->getField(1, 'field_test'));
|
||||
$this->assertEqual('', $executable->getStyle()->getField(6, 'field_test'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see CommonXssUnitTest
|
||||
*/
|
||||
class FieldFileSizeTest extends ViewUnitTestBase {
|
||||
class FieldFileSizeTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
@ -64,9 +64,9 @@ class FieldFileSizeTest extends ViewUnitTestBase {
|
|||
// Test with the bytes option.
|
||||
$view->field['age']->options['file_size_display'] = 'bytes';
|
||||
$this->assertEqual($view->field['age']->advancedRender($view->result[0]), '');
|
||||
$this->assertEqual($view->field['age']->advancedRender($view->result[1]), 10);
|
||||
$this->assertEqual($view->field['age']->advancedRender($view->result[2]), 1000);
|
||||
$this->assertEqual($view->field['age']->advancedRender($view->result[3]), 10000);
|
||||
$this->assertEqual($view->field['age']->advancedRender($view->result[1]), '10');
|
||||
$this->assertEqual($view->field['age']->advancedRender($view->result[2]), '1000');
|
||||
$this->assertEqual($view->field['age']->advancedRender($view->result[3]), '10000');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
757
core/modules/views/src/Tests/Handler/FieldKernelTest.php
Normal file
757
core/modules/views/src/Tests/Handler/FieldKernelTest.php
Normal file
|
@ -0,0 +1,757 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Tests\Handler\FieldKernelTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Plugin\views\field\FieldPluginBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the generic field handler.
|
||||
*
|
||||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\field\FieldPluginBase
|
||||
*/
|
||||
class FieldKernelTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('user');
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = array('test_view', 'test_field_tokens', 'test_field_output');
|
||||
|
||||
/**
|
||||
* Map column names.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columnMap = array(
|
||||
'views_test_data_name' => 'name',
|
||||
);
|
||||
|
||||
/**
|
||||
* Overrides Drupal\views\Tests\ViewTestBase::viewsData().
|
||||
*/
|
||||
protected function viewsData() {
|
||||
$data = parent::viewsData();
|
||||
$data['views_test_data']['job']['field']['id'] = 'test_field';
|
||||
$data['views_test_data']['job']['field']['click sortable'] = FALSE;
|
||||
$data['views_test_data']['id']['field']['click sortable'] = TRUE;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the render function is called.
|
||||
*/
|
||||
public function testRender() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$view = Views::getView('test_field_tokens');
|
||||
$this->executeView($view);
|
||||
|
||||
$random_text = $this->randomMachineName();
|
||||
$view->field['job']->setTestValue($random_text);
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['job']->theme($view->result[0]);
|
||||
});
|
||||
$this->assertEqual($output, $random_text, 'Make sure the render method rendered the manual set value.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests all things related to the query.
|
||||
*/
|
||||
public function testQuery() {
|
||||
// Tests adding additional fields to the query.
|
||||
$view = Views::getView('test_view');
|
||||
$view->initHandlers();
|
||||
|
||||
$id_field = $view->field['id'];
|
||||
$id_field->additional_fields['job'] = 'job';
|
||||
// Choose also a field alias key which doesn't match to the table field.
|
||||
$id_field->additional_fields['created_test'] = array('table' => 'views_test_data', 'field' => 'created');
|
||||
$view->build();
|
||||
|
||||
// Make sure the field aliases have the expected value.
|
||||
$this->assertEqual($id_field->aliases['job'], 'views_test_data_job');
|
||||
$this->assertEqual($id_field->aliases['created_test'], 'views_test_data_created');
|
||||
|
||||
$this->executeView($view);
|
||||
// Tests the getValue method with and without a field aliases.
|
||||
foreach ($this->dataSet() as $key => $row) {
|
||||
$id = $key + 1;
|
||||
$result = $view->result[$key];
|
||||
$this->assertEqual($id_field->getValue($result), $id);
|
||||
$this->assertEqual($id_field->getValue($result, 'job'), $row['job']);
|
||||
$this->assertEqual($id_field->getValue($result, 'created_test'), $row['created']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a string is part of another string.
|
||||
*
|
||||
* @param string $haystack
|
||||
* The value to search in.
|
||||
* @param string $needle
|
||||
* The value to search for.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion. Do not translate
|
||||
* messages: use format_string() to embed variables in the message text, not
|
||||
* t(). If left blank, a default message will be displayed.
|
||||
* @param string $group
|
||||
* (optional) The group this message is in, which is displayed in a column
|
||||
* in test output. Use 'Debug' to indicate this is debugging output. Do not
|
||||
* translate this string. Defaults to 'Other'; most tests do not override
|
||||
* this default.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the assertion succeeded, FALSE otherwise.
|
||||
*/
|
||||
protected function assertSubString($haystack, $needle, $message = '', $group = 'Other') {
|
||||
return $this->assertTrue(strpos($haystack, $needle) !== FALSE, $message, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a string is not part of another string.
|
||||
*
|
||||
* @param string $haystack
|
||||
* The value to search in.
|
||||
* @param string $needle
|
||||
* The value to search for.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion. Do not translate
|
||||
* messages: use format_string() to embed variables in the message text, not
|
||||
* t(). If left blank, a default message will be displayed.
|
||||
* @param string $group
|
||||
* (optional) The group this message is in, which is displayed in a column
|
||||
* in test output. Use 'Debug' to indicate this is debugging output. Do not
|
||||
* translate this string. Defaults to 'Other'; most tests do not override
|
||||
* this default.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the assertion succeeded, FALSE otherwise.
|
||||
*/
|
||||
protected function assertNotSubString($haystack, $needle, $message = '', $group = 'Other') {
|
||||
return $this->assertTrue(strpos($haystack, $needle) === FALSE, $message, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests general rewriting of the output.
|
||||
*/
|
||||
public function testRewrite() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$view = Views::getView('test_view');
|
||||
$view->initHandlers();
|
||||
$this->executeView($view);
|
||||
$row = $view->result[0];
|
||||
$id_field = $view->field['id'];
|
||||
|
||||
// Don't check the rewrite checkbox, so the text shouldn't appear.
|
||||
$id_field->options['alter']['text'] = $random_text = $this->randomMachineName();
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
|
||||
return $id_field->theme($row);
|
||||
});
|
||||
$this->assertNotSubString($output, $random_text);
|
||||
|
||||
$id_field->options['alter']['alter_text'] = TRUE;
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) {
|
||||
return $id_field->theme($row);
|
||||
});
|
||||
$this->assertSubString($output, $random_text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the field tokens, row level and field level.
|
||||
*/
|
||||
public function testFieldTokens() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$view = Views::getView('test_field_tokens');
|
||||
$this->executeView($view);
|
||||
$name_field_0 = $view->field['name'];
|
||||
$name_field_1 = $view->field['name_1'];
|
||||
$name_field_2 = $view->field['name_2'];
|
||||
$row = $view->result[0];
|
||||
|
||||
$name_field_0->options['alter']['alter_text'] = TRUE;
|
||||
$name_field_0->options['alter']['text'] = '{{ name }}';
|
||||
|
||||
$name_field_1->options['alter']['alter_text'] = TRUE;
|
||||
$name_field_1->options['alter']['text'] = '{{ name_1 }} {{ name }}';
|
||||
|
||||
$name_field_2->options['alter']['alter_text'] = TRUE;
|
||||
$name_field_2->options['alter']['text'] = '{% if name_2|length > 3 %}{{ name_2 }} {{ name_1 }}{% endif %}';
|
||||
|
||||
foreach ($view->result as $row) {
|
||||
$expected_output_0 = $row->views_test_data_name;
|
||||
$expected_output_1 = "$row->views_test_data_name $row->views_test_data_name";
|
||||
$expected_output_2 = "$row->views_test_data_name $row->views_test_data_name $row->views_test_data_name";
|
||||
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field_0, $row) {
|
||||
return $name_field_0->advancedRender($row);
|
||||
});
|
||||
$this->assertEqual($output, $expected_output_0, format_string('Test token replacement: "!token" gave "!output"', [
|
||||
'!token' => $name_field_0->options['alter']['text'],
|
||||
'!output' => $output,
|
||||
]));
|
||||
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field_1, $row) {
|
||||
return $name_field_1->advancedRender($row);
|
||||
});
|
||||
$this->assertEqual($output, $expected_output_1, format_string('Test token replacement: "!token" gave "!output"', [
|
||||
'!token' => $name_field_1->options['alter']['text'],
|
||||
'!output' => $output,
|
||||
]));
|
||||
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field_2, $row) {
|
||||
return $name_field_2->advancedRender($row);
|
||||
});
|
||||
$this->assertEqual($output, $expected_output_2, format_string('Test token replacement: "!token" gave "!output"', [
|
||||
'!token' => $name_field_2->options['alter']['text'],
|
||||
'!output' => $output,
|
||||
]));
|
||||
}
|
||||
|
||||
$job_field = $view->field['job'];
|
||||
$job_field->options['alter']['alter_text'] = TRUE;
|
||||
$job_field->options['alter']['text'] = '{{ job }}';
|
||||
|
||||
$random_text = $this->randomMachineName();
|
||||
$job_field->setTestValue($random_text);
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
|
||||
return $job_field->advancedRender($row);
|
||||
});
|
||||
$this->assertSubString($output, $random_text, format_string('Make sure the self token (!token => !value) appears in the output (!output)', [
|
||||
'!value' => $random_text,
|
||||
'!output' => $output,
|
||||
'!token' => $job_field->options['alter']['text'],
|
||||
]));
|
||||
|
||||
// Verify the token format used in D7 and earlier does not get substituted.
|
||||
$old_token = '[job]';
|
||||
$job_field->options['alter']['text'] = $old_token;
|
||||
$random_text = $this->randomMachineName();
|
||||
$job_field->setTestValue($random_text);
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
|
||||
return $job_field->advancedRender($row);
|
||||
});
|
||||
$this->assertEqual($output, $old_token, format_string('Make sure the old token style (!token => !value) is not changed in the output (!output)', [
|
||||
'!value' => $random_text,
|
||||
'!output' => $output,
|
||||
'!token' => $job_field->options['alter']['text'],
|
||||
]));
|
||||
|
||||
// Verify HTML tags are allowed in rewrite templates while token
|
||||
// replacements are escaped.
|
||||
$job_field->options['alter']['text'] = '<h1>{{ job }}</h1>';
|
||||
$random_text = $this->randomMachineName();
|
||||
$job_field->setTestValue('<span>' . $random_text . '</span>');
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
|
||||
return $job_field->advancedRender($row);
|
||||
});
|
||||
$this->assertEqual($output, '<h1><span>' . $random_text . '</span></h1>', 'Valid tags are allowed in rewrite templates and token replacements.');
|
||||
|
||||
// Verify <script> tags are correctly removed from rewritten text.
|
||||
$rewrite_template = '<script>alert("malicious");</script>';
|
||||
$job_field->options['alter']['text'] = $rewrite_template;
|
||||
$random_text = $this->randomMachineName();
|
||||
$job_field->setTestValue($random_text);
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
|
||||
return $job_field->advancedRender($row);
|
||||
});
|
||||
$this->assertNotSubString($output, '<script>', 'Ensure a script tag in the rewrite template is removed.');
|
||||
|
||||
$rewrite_template = '<script>{{ job }}</script>';
|
||||
$job_field->options['alter']['text'] = $rewrite_template;
|
||||
$random_text = $this->randomMachineName();
|
||||
$job_field->setTestValue($random_text);
|
||||
$output = $renderer->executeInRenderContext(new RenderContext(), function () use ($job_field, $row) {
|
||||
return $job_field->advancedRender($row);
|
||||
});
|
||||
$this->assertEqual($output, $random_text, format_string('Make sure a script tag in the template (!template) is removed, leaving only the replaced token in the output (!output)', [
|
||||
'!output' => $output,
|
||||
'!template' => $rewrite_template,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the exclude setting.
|
||||
*/
|
||||
public function testExclude() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = $this->container->get('renderer');
|
||||
$view = Views::getView('test_field_output');
|
||||
$view->initHandlers();
|
||||
// Hide the field and see whether it's rendered.
|
||||
$view->field['name']->options['exclude'] = TRUE;
|
||||
|
||||
$output = $view->preview();
|
||||
$output = $renderer->renderRoot($output);
|
||||
foreach ($this->dataSet() as $entry) {
|
||||
$this->assertNotSubString($output, $entry['name']);
|
||||
}
|
||||
|
||||
// Show and check the field.
|
||||
$view->field['name']->options['exclude'] = FALSE;
|
||||
|
||||
$output = $view->preview();
|
||||
$output = $renderer->renderRoot($output);
|
||||
foreach ($this->dataSet() as $entry) {
|
||||
$this->assertSubString($output, $entry['name']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests everything related to empty output of a field.
|
||||
*/
|
||||
function testEmpty() {
|
||||
$this->_testHideIfEmpty();
|
||||
$this->_testEmptyText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the hide if empty functionality.
|
||||
*
|
||||
* This tests alters the result to get easier and less coupled results. It is
|
||||
* important that assertIdentical() is used in this test since in PHP 0 == ''.
|
||||
*/
|
||||
function _testHideIfEmpty() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$view = Views::getView('test_view');
|
||||
$view->initDisplay();
|
||||
$this->executeView($view);
|
||||
|
||||
$column_map_reversed = array_flip($this->columnMap);
|
||||
$view->row_index = 0;
|
||||
$random_name = $this->randomMachineName();
|
||||
$random_value = $this->randomMachineName();
|
||||
|
||||
// Test when results are not rewritten and empty values are not hidden.
|
||||
$view->field['name']->options['hide_alter_empty'] = FALSE;
|
||||
$view->field['name']->options['hide_empty'] = FALSE;
|
||||
$view->field['name']->options['empty_zero'] = FALSE;
|
||||
|
||||
// Test a valid string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = $random_name;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_name, 'By default, a string should not be treated as empty.');
|
||||
|
||||
// Test an empty string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'By default, "" should not be treated as empty.');
|
||||
|
||||
// Test zero as an integer.
|
||||
$view->result[0]->{$column_map_reversed['name']} = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, '0', 'By default, 0 should not be treated as empty.');
|
||||
|
||||
// Test zero as a string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "0", 'By default, "0" should not be treated as empty.');
|
||||
|
||||
// Test when results are not rewritten and non-zero empty values are hidden.
|
||||
$view->field['name']->options['hide_alter_empty'] = TRUE;
|
||||
$view->field['name']->options['hide_empty'] = TRUE;
|
||||
$view->field['name']->options['empty_zero'] = FALSE;
|
||||
|
||||
// Test a valid string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = $random_name;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_name, 'If hide_empty is checked, a string should not be treated as empty.');
|
||||
|
||||
// Test an empty string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'If hide_empty is checked, "" should be treated as empty.');
|
||||
|
||||
// Test zero as an integer.
|
||||
$view->result[0]->{$column_map_reversed['name']} = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, '0', 'If hide_empty is checked, but not empty_zero, 0 should not be treated as empty.');
|
||||
|
||||
// Test zero as a string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "0", 'If hide_empty is checked, but not empty_zero, "0" should not be treated as empty.');
|
||||
|
||||
// Test when results are not rewritten and all empty values are hidden.
|
||||
$view->field['name']->options['hide_alter_empty'] = TRUE;
|
||||
$view->field['name']->options['hide_empty'] = TRUE;
|
||||
$view->field['name']->options['empty_zero'] = TRUE;
|
||||
|
||||
// Test zero as an integer.
|
||||
$view->result[0]->{$column_map_reversed['name']} = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'If hide_empty and empty_zero are checked, 0 should be treated as empty.');
|
||||
|
||||
// Test zero as a string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'If hide_empty and empty_zero are checked, "0" should be treated as empty.');
|
||||
|
||||
// Test when results are rewritten to a valid string and non-zero empty
|
||||
// results are hidden.
|
||||
$view->field['name']->options['hide_alter_empty'] = FALSE;
|
||||
$view->field['name']->options['hide_empty'] = TRUE;
|
||||
$view->field['name']->options['empty_zero'] = FALSE;
|
||||
$view->field['name']->options['alter']['alter_text'] = TRUE;
|
||||
$view->field['name']->options['alter']['text'] = $random_name;
|
||||
|
||||
// Test a valid string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = $random_value;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_name, 'If the rewritten string is not empty, it should not be treated as empty.');
|
||||
|
||||
// Test an empty string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_name, 'If the rewritten string is not empty, "" should not be treated as empty.');
|
||||
|
||||
// Test zero as an integer.
|
||||
$view->result[0]->{$column_map_reversed['name']} = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_name, 'If the rewritten string is not empty, 0 should not be treated as empty.');
|
||||
|
||||
// Test zero as a string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_name, 'If the rewritten string is not empty, "0" should not be treated as empty.');
|
||||
|
||||
// Test when results are rewritten to an empty string and non-zero empty results are hidden.
|
||||
$view->field['name']->options['hide_alter_empty'] = TRUE;
|
||||
$view->field['name']->options['hide_empty'] = TRUE;
|
||||
$view->field['name']->options['empty_zero'] = FALSE;
|
||||
$view->field['name']->options['alter']['alter_text'] = TRUE;
|
||||
$view->field['name']->options['alter']['text'] = "";
|
||||
|
||||
// Test a valid string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = $random_name;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_name, 'If the rewritten string is empty, it should not be treated as empty.');
|
||||
|
||||
// Test an empty string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'If the rewritten string is empty, "" should be treated as empty.');
|
||||
|
||||
// Test zero as an integer.
|
||||
$view->result[0]->{$column_map_reversed['name']} = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, '0', 'If the rewritten string is empty, 0 should not be treated as empty.');
|
||||
|
||||
// Test zero as a string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "0", 'If the rewritten string is empty, "0" should not be treated as empty.');
|
||||
|
||||
// Test when results are rewritten to zero as a string and non-zero empty
|
||||
// results are hidden.
|
||||
$view->field['name']->options['hide_alter_empty'] = FALSE;
|
||||
$view->field['name']->options['hide_empty'] = TRUE;
|
||||
$view->field['name']->options['empty_zero'] = FALSE;
|
||||
$view->field['name']->options['alter']['alter_text'] = TRUE;
|
||||
$view->field['name']->options['alter']['text'] = "0";
|
||||
|
||||
// Test a valid string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = $random_name;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "0", 'If the rewritten string is zero and empty_zero is not checked, the string rewritten as 0 should not be treated as empty.');
|
||||
|
||||
// Test an empty string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "0", 'If the rewritten string is zero and empty_zero is not checked, "" rewritten as 0 should not be treated as empty.');
|
||||
|
||||
// Test zero as an integer.
|
||||
$view->result[0]->{$column_map_reversed['name']} = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "0", 'If the rewritten string is zero and empty_zero is not checked, 0 should not be treated as empty.');
|
||||
|
||||
// Test zero as a string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "0", 'If the rewritten string is zero and empty_zero is not checked, "0" should not be treated as empty.');
|
||||
|
||||
// Test when results are rewritten to a valid string and non-zero empty
|
||||
// results are hidden.
|
||||
$view->field['name']->options['hide_alter_empty'] = TRUE;
|
||||
$view->field['name']->options['hide_empty'] = TRUE;
|
||||
$view->field['name']->options['empty_zero'] = FALSE;
|
||||
$view->field['name']->options['alter']['alter_text'] = TRUE;
|
||||
$view->field['name']->options['alter']['text'] = $random_value;
|
||||
|
||||
// Test a valid string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = $random_name;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_value, 'If the original and rewritten strings are valid, it should not be treated as empty.');
|
||||
|
||||
// Test an empty string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'If either the original or rewritten string is invalid, "" should be treated as empty.');
|
||||
|
||||
// Test zero as an integer.
|
||||
$view->result[0]->{$column_map_reversed['name']} = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_value, 'If the original and rewritten strings are valid, 0 should not be treated as empty.');
|
||||
|
||||
// Test zero as a string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $random_value, 'If the original and rewritten strings are valid, "0" should not be treated as empty.');
|
||||
|
||||
// Test when results are rewritten to zero as a string and all empty
|
||||
// original values and results are hidden.
|
||||
$view->field['name']->options['hide_alter_empty'] = TRUE;
|
||||
$view->field['name']->options['hide_empty'] = TRUE;
|
||||
$view->field['name']->options['empty_zero'] = TRUE;
|
||||
$view->field['name']->options['alter']['alter_text'] = TRUE;
|
||||
$view->field['name']->options['alter']['text'] = "0";
|
||||
|
||||
// Test a valid string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = $random_name;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "", 'If the rewritten string is zero, it should be treated as empty.');
|
||||
|
||||
// Test an empty string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'If the rewritten string is zero, "" should be treated as empty.');
|
||||
|
||||
// Test zero as an integer.
|
||||
$view->result[0]->{$column_map_reversed['name']} = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'If the rewritten string is zero, 0 should not be treated as empty.');
|
||||
|
||||
// Test zero as a string.
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, "", 'If the rewritten string is zero, "0" should not be treated as empty.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the usage of the empty text.
|
||||
*/
|
||||
function _testEmptyText() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$view = Views::getView('test_view');
|
||||
$view->initDisplay();
|
||||
$this->executeView($view);
|
||||
|
||||
$column_map_reversed = array_flip($this->columnMap);
|
||||
$view->row_index = 0;
|
||||
|
||||
$empty_text = $view->field['name']->options['empty'] = $this->randomMachineName();
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $empty_text, 'If a field is empty, the empty text should be used for the output.');
|
||||
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, "0", 'If a field is 0 and empty_zero is not checked, the empty text should not be used for the output.');
|
||||
|
||||
$view->result[0]->{$column_map_reversed['name']} = "0";
|
||||
$view->field['name']->options['empty_zero'] = TRUE;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $empty_text, 'If a field is 0 and empty_zero is checked, the empty text should be used for the output.');
|
||||
|
||||
$view->result[0]->{$column_map_reversed['name']} = "";
|
||||
$view->field['name']->options['alter']['alter_text'] = TRUE;
|
||||
$alter_text = $view->field['name']->options['alter']['text'] = $this->randomMachineName();
|
||||
$view->field['name']->options['hide_alter_empty'] = FALSE;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $alter_text, 'If a field is empty, some rewrite text exists, but hide_alter_empty is not checked, render the rewrite text.');
|
||||
|
||||
$view->field['name']->options['hide_alter_empty'] = TRUE;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical((string) $render, $empty_text, 'If a field is empty, some rewrite text exists, and hide_alter_empty is checked, use the empty text.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests views_handler_field::isValueEmpty().
|
||||
*/
|
||||
function testIsValueEmpty() {
|
||||
$view = Views::getView('test_view');
|
||||
$view->initHandlers();
|
||||
$field = $view->field['name'];
|
||||
|
||||
$this->assertFalse($field->isValueEmpty("not empty", TRUE), 'A normal string is not empty.');
|
||||
$this->assertTrue($field->isValueEmpty("not empty", TRUE, FALSE), 'A normal string which skips empty() can be seen as empty.');
|
||||
|
||||
$this->assertTrue($field->isValueEmpty("", TRUE), '"" is considered as empty.');
|
||||
|
||||
$this->assertTrue($field->isValueEmpty('0', TRUE), '"0" is considered as empty if empty_zero is TRUE.');
|
||||
$this->assertTrue($field->isValueEmpty(0, TRUE), '0 is considered as empty if empty_zero is TRUE.');
|
||||
$this->assertFalse($field->isValueEmpty('0', FALSE), '"0" is considered not as empty if empty_zero is FALSE.');
|
||||
$this->assertFalse($field->isValueEmpty(0, FALSE), '0 is considered not as empty if empty_zero is FALSE.');
|
||||
|
||||
$this->assertTrue($field->isValueEmpty(NULL, TRUE, TRUE), 'Null should be always seen as empty, regardless of no_skip_empty.');
|
||||
$this->assertTrue($field->isValueEmpty(NULL, TRUE, FALSE), 'Null should be always seen as empty, regardless of no_skip_empty.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the filters are click sortable as expected.
|
||||
*/
|
||||
public function testClickSortable() {
|
||||
// Test that clickSortable is TRUE by default.
|
||||
$item = array(
|
||||
'table' => 'views_test_data',
|
||||
'field' => 'name',
|
||||
);
|
||||
$plugin = $this->container->get('plugin.manager.views.field')->getHandler($item);
|
||||
$this->assertTrue($plugin->clickSortable(), 'TRUE as a default value is correct.');
|
||||
|
||||
// Test that clickSortable is TRUE by when set TRUE in the data.
|
||||
$item['field'] = 'id';
|
||||
$plugin = $this->container->get('plugin.manager.views.field')->getHandler($item);
|
||||
$this->assertTrue($plugin->clickSortable(), 'TRUE as a views data value is correct.');
|
||||
|
||||
// Test that clickSortable is FALSE by when set FALSE in the data.
|
||||
$item['field'] = 'job';
|
||||
$plugin = $this->container->get('plugin.manager.views.field')->getHandler($item);
|
||||
$this->assertFalse($plugin->clickSortable(), 'FALSE as a views data value is correct.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the trimText method.
|
||||
*/
|
||||
public function testTrimText() {
|
||||
// Test unicode. See https://www.drupal.org/node/513396#comment-2839416.
|
||||
$text = array(
|
||||
'Tuy nhiên, những hi vọng',
|
||||
'Giả sử chúng tôi có 3 Apple',
|
||||
'siêu nhỏ này là bộ xử lý',
|
||||
'Di động của nhà sản xuất Phần Lan',
|
||||
'khoảng cách từ đại lí đến',
|
||||
'của hãng bao gồm ba dòng',
|
||||
'сд асд асд ас',
|
||||
'асд асд асд ас'
|
||||
);
|
||||
// Just test maxlength without word boundary.
|
||||
$alter = array(
|
||||
'max_length' => 10,
|
||||
);
|
||||
$expect = array(
|
||||
'Tuy nhiên,',
|
||||
'Giả sử chú',
|
||||
'siêu nhỏ n',
|
||||
'Di động củ',
|
||||
'khoảng các',
|
||||
'của hãng b',
|
||||
'сд асд асд',
|
||||
'асд асд ас',
|
||||
);
|
||||
|
||||
foreach ($text as $key => $line) {
|
||||
$result_text = FieldPluginBase::trimText($alter, $line);
|
||||
$this->assertEqual($result_text, $expect[$key]);
|
||||
}
|
||||
|
||||
// Test also word_boundary
|
||||
$alter['word_boundary'] = TRUE;
|
||||
$expect = array(
|
||||
'Tuy nhiên',
|
||||
'Giả sử',
|
||||
'siêu nhỏ',
|
||||
'Di động',
|
||||
'khoảng',
|
||||
'của hãng',
|
||||
'сд асд',
|
||||
'асд асд',
|
||||
);
|
||||
|
||||
foreach ($text as $key => $line) {
|
||||
$result_text = FieldPluginBase::trimText($alter, $line);
|
||||
$this->assertEqual($result_text, $expect[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FieldUrlTest extends ViewUnitTestBase {
|
||||
class FieldUrlTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('system');
|
||||
|
||||
|
|
|
@ -400,7 +400,7 @@ class FieldWebTest extends HandlerTestBase {
|
|||
$output = $view->preview();
|
||||
$output = $renderer->renderRoot($output);
|
||||
$this->assertFalse($this->xpathContent($output, '//div[contains(@class, :class)]', array(':class' => 'field-content')));
|
||||
$this->assertFalse($this->xpathContent($output, '//div[contains(@class, :class)]', array(':class' => 'field-label')));
|
||||
$this->assertFalse($this->xpathContent($output, '//div[contains(@class, :class)]', array(':class' => 'field__label')));
|
||||
|
||||
$id_field->options['element_default_classes'] = TRUE;
|
||||
$output = $view->preview();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\filter\BooleanOperatorString
|
||||
*/
|
||||
class FilterBooleanOperatorStringTest extends ViewUnitTestBase {
|
||||
class FilterBooleanOperatorStringTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* The modules to enable for this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\filter\BooleanOperator
|
||||
*/
|
||||
class FilterBooleanOperatorTest extends ViewUnitTestBase {
|
||||
class FilterBooleanOperatorTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* The modules to enable for this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FilterCombineTest extends ViewUnitTestBase {
|
||||
class FilterCombineTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FilterEqualityTest extends ViewUnitTestBase {
|
||||
class FilterEqualityTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('system');
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FilterInOperatorTest extends ViewUnitTestBase {
|
||||
class FilterInOperatorTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('system');
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FilterNumericTest extends ViewUnitTestBase {
|
||||
class FilterNumericTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('system');
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class FilterStringTest extends ViewUnitTestBase {
|
||||
class FilterStringTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('system');
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class HandlerAliasTest extends ViewUnitTestBase {
|
||||
class HandlerAliasTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('user');
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class SortDateTest extends ViewUnitTestBase {
|
||||
class SortDateTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\views\Tests\Handler;
|
|||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class SortRandomTest extends ViewUnitTestBase {
|
||||
class SortRandomTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class SortTest extends ViewUnitTestBase {
|
||||
class SortTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -16,7 +16,7 @@ use Drupal\views\Plugin\views\filter\Standard;
|
|||
use Drupal\views\Views;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
|
||||
class ModuleTest extends ViewUnitTestBase {
|
||||
class ModuleTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -94,11 +94,11 @@ class ArgumentDefaultTest extends PluginTestBase {
|
|||
// Note, the undefined index error has two spaces after it.
|
||||
$error = array(
|
||||
'%type' => 'Notice',
|
||||
'!message' => 'Undefined index: ' . $argument_type,
|
||||
'@message' => 'Undefined index: ' . $argument_type,
|
||||
'%function' => 'views_handler_argument->validateOptionsForm()',
|
||||
);
|
||||
$message = t('%type: !message in %function', $error);
|
||||
$this->assertNoRaw($message, t('Did not find error message: !message.', array('!message' => $message)));
|
||||
$message = t('%type: @message in %function', $error);
|
||||
$this->assertNoRaw($message, format_string('Did not find error message: @message.', array('@message' => $message)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class ArgumentValidatorTest extends ViewUnitTestBase {
|
||||
class ArgumentValidatorTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests views block config dependencies functionality.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class BlockDependenciesTest extends ViewUnitTestBase {
|
||||
class BlockDependenciesTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\views\Tests\Plugin;
|
|||
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views_test_data\Plugin\views\filter\FilterTest as FilterPlugin;
|
||||
|
||||
|
@ -19,7 +19,7 @@ use Drupal\views_test_data\Plugin\views\filter\FilterTest as FilterPlugin;
|
|||
* @group views
|
||||
* @see views_plugin_cache
|
||||
*/
|
||||
class CacheTest extends ViewUnitTestBase {
|
||||
class CacheTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
122
core/modules/views/src/Tests/Plugin/DisplayKernelTest.php
Normal file
122
core/modules/views/src/Tests/Plugin/DisplayKernelTest.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Tests\Plugin\DisplayKernelTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Plugin\views\style\StylePluginBase;
|
||||
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
||||
use Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase;
|
||||
use Drupal\views\Plugin\views\pager\PagerPluginBase;
|
||||
use Drupal\views\Plugin\views\query\QueryPluginBase;
|
||||
use Drupal\views\Plugin\views\cache\CachePluginBase;
|
||||
use Drupal\views\Plugin\views\row\RowPluginBase;
|
||||
|
||||
/**
|
||||
* Drupal unit tests for the DisplayPluginBase class.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class DisplayKernelTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('block', 'node', 'field', 'user');
|
||||
|
||||
/**
|
||||
* Views plugin types to test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pluginTypes = array(
|
||||
'access',
|
||||
'cache',
|
||||
'query',
|
||||
'exposed_form',
|
||||
'pager',
|
||||
'style',
|
||||
'row',
|
||||
);
|
||||
|
||||
/**
|
||||
* Views handler types to test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $handlerTypes = array(
|
||||
'fields',
|
||||
'sorts',
|
||||
);
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = array('test_display_defaults');
|
||||
|
||||
/**
|
||||
* Tests the default display options.
|
||||
*/
|
||||
public function testDefaultOptions() {
|
||||
// Save the view.
|
||||
$view = Views::getView('test_display_defaults');
|
||||
$view->mergeDefaults();
|
||||
$view->save();
|
||||
|
||||
// Reload to get saved storage values.
|
||||
$view = Views::getView('test_display_defaults');
|
||||
$view->initDisplay();
|
||||
$display_data = $view->storage->get('display');
|
||||
|
||||
foreach ($view->displayHandlers as $id => $display) {
|
||||
// Test the view plugin options against the storage.
|
||||
foreach ($this->pluginTypes as $type) {
|
||||
$options = $display->getOption($type);
|
||||
$this->assertIdentical($display_data[$id]['display_options'][$type]['options'], $options['options']);
|
||||
}
|
||||
// Test the view handler options against the storage.
|
||||
foreach ($this->handlerTypes as $type) {
|
||||
$options = $display->getOption($type);
|
||||
$this->assertIdentical($display_data[$id]['display_options'][$type], $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the \Drupal\views\Plugin\views\display\DisplayPluginBase::getPlugin() method.
|
||||
*/
|
||||
public function testGetPlugin() {
|
||||
$view = Views::getView('test_display_defaults');
|
||||
$view->initDisplay();
|
||||
$display_handler = $view->display_handler;
|
||||
|
||||
$this->assertTrue($display_handler->getPlugin('access') instanceof AccessPluginBase, 'An access plugin instance was returned.');
|
||||
$this->assertTrue($display_handler->getPlugin('cache') instanceof CachePluginBase, 'A cache plugin instance was returned.');
|
||||
$this->assertTrue($display_handler->getPlugin('exposed_form') instanceof ExposedFormPluginBase, 'An exposed_form plugin instance was returned.');
|
||||
$this->assertTrue($display_handler->getPlugin('pager') instanceof PagerPluginBase, 'A pager plugin instance was returned.');
|
||||
$this->assertTrue($display_handler->getPlugin('query') instanceof QueryPluginBase, 'A query plugin instance was returned.');
|
||||
$this->assertTrue($display_handler->getPlugin('row') instanceof RowPluginBase, 'A row plugin instance was returned.');
|
||||
$this->assertTrue($display_handler->getPlugin('style') instanceof StylePluginBase, 'A style plugin instance was returned.');
|
||||
// Test that nothing is returned when an invalid type is requested.
|
||||
$this->assertNull($display_handler->getPlugin('invalid'), 'NULL was returned for an invalid instance');
|
||||
// Test that nothing was returned for an instance with no 'type' in options.
|
||||
unset($display_handler->options['access']);
|
||||
$this->assertNull($display_handler->getPlugin('access'), 'NULL was returned for a plugin type with no "type" option');
|
||||
|
||||
// Get a plugin twice, and make sure the same instance is returned.
|
||||
$view->destroy();
|
||||
$view->initDisplay();
|
||||
$first = spl_object_hash($display_handler->getPlugin('style'));
|
||||
$second = spl_object_hash($display_handler->getPlugin('style'));
|
||||
$this->assertIdentical($first, $second, 'The same plugin instance was returned.');
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,7 @@ namespace Drupal\views\Tests\Plugin;
|
|||
use Drupal\Core\Menu\MenuTreeParameters;
|
||||
use Drupal\Core\Session\AnonymousUserSession;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
|
@ -21,7 +21,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\display\Page
|
||||
*/
|
||||
class DisplayPageTest extends ViewUnitTestBase {
|
||||
class DisplayPageTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -24,19 +24,23 @@ class DisplayPageWebTest extends PluginTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = array('test_page_display', 'test_page_display_arguments', 'test_page_display_menu');
|
||||
public static $testViews = array('test_page_display', 'test_page_display_arguments', 'test_page_display_menu', 'test_page_display_path');
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['menu_ui', 'block'];
|
||||
public static $modules = ['menu_ui', 'block', 'views_ui'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->enableViewsTestModule();
|
||||
$this->drupalPlaceBlock('local_tasks_block');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,7 +57,7 @@ class DisplayPageWebTest extends PluginTestBase {
|
|||
|
||||
$this->drupalGet('test_route_with_argument/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertCacheContexts(['languages:language_interface', 'theme', 'url']);
|
||||
$this->assertCacheContexts(['languages:language_interface', 'route.name', 'theme', 'url']);
|
||||
$result = $this->xpath('//span[@class="field-content"]');
|
||||
$this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
|
||||
$this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
|
||||
|
@ -138,4 +142,36 @@ class DisplayPageWebTest extends PluginTestBase {
|
|||
$this->assertFalse($xpath, 'The view title was not displayed in the view markup.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the views page path functionality.
|
||||
*/
|
||||
public function testPagePaths() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->assertPagePath('0');
|
||||
$this->assertPagePath('9999');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can successfully change a view page display path.
|
||||
*
|
||||
* @param string $path
|
||||
* Path that will be set as the view page display path.
|
||||
*
|
||||
* @return boolean
|
||||
* Assertion result.
|
||||
*/
|
||||
public function assertPagePath($path) {
|
||||
$view = Views::getView('test_page_display_path');
|
||||
$view->initDisplay('page_1');
|
||||
$view->displayHandlers->get('page_1')->overrideOption('path', $path);
|
||||
$view->save();
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
// Check if we successfully changed the path.
|
||||
$this->drupalGet($path);
|
||||
$success = $this->assertResponse(200);
|
||||
// Check if we don't get any error on the view edit page.
|
||||
$this->drupalGet('admin/structure/views/view/test_page_display_path');
|
||||
return $success && $this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@ class ExposedFormTest extends ViewTestBase {
|
|||
'entity_test_view_grants',
|
||||
'theme',
|
||||
'url.query_args',
|
||||
'user.roles:authenticated',
|
||||
'languages:language_content'
|
||||
];
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class PagerKernelTest extends ViewUnitTestBase {
|
||||
class PagerKernelTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
61
core/modules/views/src/Tests/Plugin/PluginBaseTest.php
Normal file
61
core/modules/views/src/Tests/Plugin/PluginBaseTest.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Tests\Plugin\PluginBaseTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\Core\Render\SafeString;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
use Drupal\views\Plugin\views\PluginBase;
|
||||
|
||||
/**
|
||||
* Tests the PluginBase class.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class PluginBaseTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* @var TestPluginBase
|
||||
*/
|
||||
var $testPluginBase;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->testPluginBase = new TestPluginBase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the token replacement in views works correctly.
|
||||
*/
|
||||
public function testViewsTokenReplace() {
|
||||
$text = '{{ langcode__value }} means {{ langcode }}';
|
||||
$tokens = ['{{ langcode }}' => SafeString::create('English'), '{{ langcode__value }}' => 'en'];
|
||||
|
||||
$result = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($text, $tokens) {
|
||||
return $this->testPluginBase->viewsTokenReplace($text, $tokens);
|
||||
});
|
||||
|
||||
$this->assertIdentical($result, 'en means English');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for using the PluginBase abstract class.
|
||||
*/
|
||||
class TestPluginBase extends PluginBase {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct([], '', []);
|
||||
}
|
||||
|
||||
public function viewsTokenReplace($text, $tokens) {
|
||||
return parent::viewsTokenReplace($text, $tokens);
|
||||
}
|
||||
|
||||
}
|
17
core/modules/views/src/Tests/Plugin/PluginKernelTestBase.php
Normal file
17
core/modules/views/src/Tests/Plugin/PluginKernelTestBase.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Tests\Plugin\PluginKernelTestBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
|
||||
/**
|
||||
* Base test class for views plugin unit tests.
|
||||
*/
|
||||
abstract class PluginKernelTestBase extends ViewKernelTestBase {
|
||||
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views_test_data\Plugin\views\query\QueryTest as QueryTestPlugin;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views_test_data\Plugin\views\query\QueryTest as QueryTestPlugin;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class QueryTest extends ViewUnitTestBase {
|
||||
class QueryTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
* @see \Drupal\views\Tests\Handler\JoinTest
|
||||
* @see \Drupal\views\Tests\Plugin\RelationshipTest
|
||||
*/
|
||||
abstract class RelationshipJoinTestBase extends PluginUnitTestBase {
|
||||
abstract class RelationshipJoinTestBase extends PluginKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
@ -30,7 +30,7 @@ abstract class RelationshipJoinTestBase extends PluginUnitTestBase {
|
|||
protected $rootUser;
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Tests\ViewUnitTestBase::setUpFixtures().
|
||||
* Overrides \Drupal\views\Tests\ViewKernelTestBase::setUpFixtures().
|
||||
*/
|
||||
protected function setUpFixtures() {
|
||||
$this->installEntitySchema('user');
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\views\Tests\Plugin;
|
|||
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the generic entity row plugin.
|
||||
|
@ -17,7 +17,7 @@ use Drupal\views\Tests\ViewUnitTestBase;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\row\EntityRow
|
||||
*/
|
||||
class RowEntityTest extends ViewUnitTestBase {
|
||||
class RowEntityTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
|
|
@ -12,7 +12,7 @@ use Drupal\node\Entity\Node;
|
|||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\simpletest\UserCreationTrait;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class RowRenderCacheTest extends ViewUnitTestBase {
|
||||
class RowRenderCacheTest extends ViewKernelTestBase {
|
||||
|
||||
use UserCreationTrait;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\query\Sql
|
||||
*/
|
||||
class SqlQueryTest extends ViewUnitTestBase {
|
||||
class SqlQueryTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ use Drupal\views\Views;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\style\HtmlList
|
||||
*/
|
||||
class StyleHtmlListTest extends ViewUnitTestBase {
|
||||
class StyleHtmlListTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -53,7 +53,7 @@ class StyleMappingTest extends StyleTestBase {
|
|||
$output = $view->preview();
|
||||
$rendered_output = \Drupal::service('renderer')->renderRoot($output);
|
||||
$this->storeViewPreview($rendered_output);
|
||||
$rows = $this->elements->body->div->div->div;
|
||||
$rows = $this->elements->body->div->div;
|
||||
$data_set = $this->dataSet();
|
||||
|
||||
$count = 0;
|
||||
|
|
|
@ -109,4 +109,31 @@ class StyleTableTest extends PluginTestBase {
|
|||
$this->assertTrue(count($result), 'Ensure the job column values are joined into a single column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a number with the value of "0" is displayed in the table.
|
||||
*/
|
||||
public function testNumericFieldVisible() {
|
||||
// Adds a new datapoint in the views_test_data table to have a person with
|
||||
// an age of zero.
|
||||
$data_set = $this->dataSet();
|
||||
$query = db_insert('views_test_data')
|
||||
->fields(array_keys($data_set[0]));
|
||||
$query->values(array(
|
||||
'name' => 'James McCartney',
|
||||
'age' => 0,
|
||||
'job' => 'Baby',
|
||||
'created' => gmmktime(6, 30, 10, 1, 1, 2000),
|
||||
'status' => 1,
|
||||
));
|
||||
$query->execute();
|
||||
|
||||
$this->drupalGet('test-table');
|
||||
|
||||
$result = $this->xpath('//tbody/tr/td[contains(., "Baby")]');
|
||||
$this->assertTrue(count($result), 'Ensure that the baby is found.');
|
||||
|
||||
$result = $this->xpath('//tbody/tr/td[text()=0]');
|
||||
$this->assertTrue(count($result), 'Ensure that the baby\'s age is shown');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use Symfony\Component\HttpFoundation\Request;
|
|||
* @group views
|
||||
* @see \Drupal\views\Plugin\views\style\Table
|
||||
*/
|
||||
class StyleTableUnitTest extends PluginUnitTestBase {
|
||||
class StyleTableUnitTest extends PluginKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Masterminds\HTML5;
|
||||
|
||||
/**
|
||||
* Tests some general style plugin related functionality.
|
||||
*/
|
||||
abstract class StyleTestBase extends ViewUnitTestBase {
|
||||
abstract class StyleTestBase extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Stores the SimpleXML representation of the output.
|
||||
|
|
|
@ -32,7 +32,7 @@ class StyleUnformattedTest extends StyleTestBase {
|
|||
$output = $view->preview();
|
||||
$this->storeViewPreview(\Drupal::service('renderer')->renderRoot($output));
|
||||
|
||||
$rows = $this->elements->body->div->div->div;
|
||||
$rows = $this->elements->body->div->div;
|
||||
$count = 0;
|
||||
$count_result = count($view->result);
|
||||
foreach ($rows as $row) {
|
||||
|
|
|
@ -10,14 +10,14 @@ namespace Drupal\views\Tests\Plugin;
|
|||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\views\Plugin\Block\ViewsBlock;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests native behaviors of the block views plugin.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class ViewsBlockTest extends ViewUnitTestBase {
|
||||
class ViewsBlockTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Tests\Plugin\ViewsSqlExceptionTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
use Drupal\views\Views;
|
||||
use Drupal\Core\Database\DatabaseExceptionWrapper;
|
||||
|
||||
/**
|
||||
* Tests the views exception handling.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class ViewsSqlExceptionTest extends PluginTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = array('test_filter');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->enableViewsTestModule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\views\Tests\ViewTestBase::viewsData().
|
||||
*/
|
||||
protected function viewsData() {
|
||||
$data = parent::viewsData();
|
||||
$data['views_test_data']['name']['filter']['id'] = 'test_exception_filter';
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for the SQL exception.
|
||||
*/
|
||||
public function testSqlException() {
|
||||
$view = Views::getView('test_filter');
|
||||
$view->initDisplay();
|
||||
|
||||
// Adding a filter that will result in an invalid query.
|
||||
$view->displayHandlers->get('default')->overrideOption('filters', array(
|
||||
'test_filter' => array(
|
||||
'id' => 'test_exception_filter',
|
||||
'table' => 'views_test_data',
|
||||
'field' => 'name',
|
||||
'operator' => '=',
|
||||
'value' => 'John',
|
||||
'group' => 0,
|
||||
),
|
||||
));
|
||||
|
||||
try {
|
||||
$this->executeView($view);
|
||||
$this->fail('Expected exception not thrown.');
|
||||
}
|
||||
catch (DatabaseExceptionWrapper $e) {
|
||||
$exception_assert_message = "Exception in {$view->storage->label()}[{$view->storage->id()}]";
|
||||
$this->assertEqual(strstr($e->getMessage(), ':', TRUE), $exception_assert_message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class PluginInstanceTest extends ViewUnitTestBase {
|
||||
class PluginInstanceTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* All views plugin types.
|
||||
|
|
|
@ -18,7 +18,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class QueryGroupByTest extends ViewUnitTestBase {
|
||||
class QueryGroupByTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
|
|
|
@ -19,7 +19,7 @@ use Drupal\views\Entity\View;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class RenderCacheIntegrationTest extends ViewUnitTestBase {
|
||||
class RenderCacheIntegrationTest extends ViewKernelTestBase {
|
||||
|
||||
use AssertViewsCacheTagsTrait;
|
||||
|
||||
|
|
|
@ -101,6 +101,39 @@ class SearchIntegrationTest extends ViewTestBase {
|
|||
$this->assertNoLink('pizza');
|
||||
$this->assertNoLink('sandwich');
|
||||
$this->assertOneLink('cola');
|
||||
|
||||
// Test sorting.
|
||||
$node = [
|
||||
'title' => "Drupal's search rocks.",
|
||||
'type' => $type->id(),
|
||||
];
|
||||
$this->drupalCreateNode($node);
|
||||
$node['title'] = "Drupal's search rocks <em>really</em> rocks!";
|
||||
$this->drupalCreateNode($node);
|
||||
$this->cronRun();
|
||||
$this->drupalGet('test-arg/rocks');
|
||||
$xpath = '//div[@class="views-row"]//a';
|
||||
/** @var \SimpleXMLElement[] $results */
|
||||
$results = $this->xpath($xpath);
|
||||
$this->assertEqual((string) $results[0], "Drupal's search rocks <em>really</em> rocks!");
|
||||
$this->assertEqual((string) $results[1], "Drupal's search rocks.");
|
||||
$this->assertEscaped("Drupal's search rocks <em>really</em> rocks!");
|
||||
|
||||
// Test sorting with another set of titles.
|
||||
$node = [
|
||||
'title' => "Testing one two two two",
|
||||
'type' => $type->id(),
|
||||
];
|
||||
$this->drupalCreateNode($node);
|
||||
$node['title'] = "Testing one one one";
|
||||
$this->drupalCreateNode($node);
|
||||
$this->cronRun();
|
||||
$this->drupalGet('test-arg/one');
|
||||
$xpath = '//div[@class="views-row"]//a';
|
||||
/** @var \SimpleXMLElement[] $results */
|
||||
$results = $this->xpath($xpath);
|
||||
$this->assertEqual((string) $results[0], "Testing one one one");
|
||||
$this->assertEqual((string) $results[1], "Testing one two two two");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group views
|
||||
*/
|
||||
class TokenReplaceTest extends ViewUnitTestBase {
|
||||
class TokenReplaceTest extends ViewKernelTestBase {
|
||||
|
||||
public static $modules = array('system');
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Tests\Update\EntityViewsDataUpdateFilledTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests\Update;
|
||||
|
||||
/**
|
||||
* Runs EntityViewsDataUpdateTest with a dump filled with content.
|
||||
*
|
||||
* @group Update
|
||||
*/
|
||||
class EntityViewsDataUpdateFilledTest extends EntityViewsDataUpdateTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
parent::setDatabaseDumpFiles();
|
||||
$this->databaseDumpFiles[0] = __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Tests\Update\EntityViewsDataUpdateTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests\Update;
|
||||
|
||||
use Drupal\system\Tests\Update\UpdatePathTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the upgrade path for views field plugins.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2455125
|
||||
*
|
||||
* @group Update
|
||||
*/
|
||||
class EntityViewsDataUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that field plugins are updated properly.
|
||||
*/
|
||||
public function testUpdateHookN() {
|
||||
$this->runUpdates();
|
||||
|
||||
// Load and initialize our test view.
|
||||
$view = Views::getView('update_test');
|
||||
$view->initHandlers();
|
||||
|
||||
// Extract the fields from the test view that were updated.
|
||||
/** @var \Drupal\views\Plugin\views\field\Field $field */
|
||||
$created = $view->field['created'];
|
||||
/** @var \Drupal\views\Plugin\views\field\Field $field */
|
||||
$created_1 = $view->field['created_1'];
|
||||
/** @var \Drupal\views\Plugin\views\field\Field $field */
|
||||
$created_2 = $view->field['created_2'];
|
||||
|
||||
// Make sure the plugins were converted from date to field.
|
||||
$this->assertEqual($created->getPluginId(), 'field', 'created has correct plugin_id');
|
||||
$this->assertEqual($created_1->getPluginId(), 'field', 'created has correct plugin_id');
|
||||
$this->assertEqual($created_2->getPluginId(), 'field', 'created has correct plugin_id');
|
||||
|
||||
// Check options on 'created'.
|
||||
$options = $created->options;
|
||||
$this->assertEqual($options['type'], 'timestamp');
|
||||
$this->assertFalse(array_key_exists('date_format', $options));
|
||||
$this->assertFalse(array_key_exists('custom_date_format', $options));
|
||||
$this->assertFalse(array_key_exists('timezone', $options));
|
||||
$this->assertEqual($options['settings']['date_format'], 'long');
|
||||
$this->assertEqual($options['settings']['custom_date_format'], '');
|
||||
$this->assertEqual($options['settings']['timezone'], 'Africa/Abidjan');
|
||||
|
||||
// Check options on 'created'.
|
||||
$options = $created_1->options;
|
||||
$this->assertEqual($options['type'], 'timestamp_ago');
|
||||
$this->assertFalse(array_key_exists('date_format', $options));
|
||||
$this->assertFalse(array_key_exists('custom_date_format', $options));
|
||||
$this->assertFalse(array_key_exists('timezone', $options));
|
||||
$this->assertEqual($options['settings']['future_format'], '@interval');
|
||||
$this->assertEqual($options['settings']['past_format'], '@interval');
|
||||
$this->assertEqual($options['settings']['granularity'], 2);
|
||||
|
||||
// Check options on 'created'.
|
||||
$options = $created_2->options;
|
||||
$this->assertEqual($options['type'], 'timestamp_ago');
|
||||
$this->assertFalse(array_key_exists('date_format', $options));
|
||||
$this->assertFalse(array_key_exists('custom_date_format', $options));
|
||||
$this->assertFalse(array_key_exists('timezone', $options));
|
||||
$this->assertEqual($options['settings']['future_format'], '@interval hence');
|
||||
$this->assertEqual($options['settings']['past_format'], '@interval ago');
|
||||
$this->assertEqual($options['settings']['granularity'], 2);
|
||||
}
|
||||
|
||||
}
|
|
@ -127,7 +127,7 @@ class ViewElementTest extends ViewTestBase {
|
|||
|
||||
// Set the content as our rendered array.
|
||||
$render = $this->render;
|
||||
$render['#embed'] = TRUE;
|
||||
$render['view']['#embed'] = TRUE;
|
||||
$this->setRawContent($renderer->renderRoot($render));
|
||||
|
||||
$xpath = $this->xpath('//div[@class="views-element-container"]');
|
||||
|
@ -173,7 +173,7 @@ class ViewElementTest extends ViewTestBase {
|
|||
|
||||
// Test the render array again.
|
||||
$render = $this->render;
|
||||
$render['#embed'] = TRUE;
|
||||
$render['view']['#embed'] = TRUE;
|
||||
$this->setRawContent($renderer->renderRoot($render));
|
||||
// There should be 1 row in the results, 'John' arg 25.
|
||||
$xpath = $this->xpath('//div[@class="view-content"]/div');
|
||||
|
@ -183,6 +183,15 @@ class ViewElementTest extends ViewTestBase {
|
|||
$this->drupalGet('views_test_data_element_embed_form');
|
||||
$xpath = $this->xpath('//div[@class="view-content"]/div');
|
||||
$this->assertEqual(count($xpath), 1);
|
||||
|
||||
// Tests the render array with an exposed filter.
|
||||
$render = $this->render;
|
||||
$render['view']['#display_id'] = 'embed_2';
|
||||
$render['view']['#embed'] = TRUE;
|
||||
$this->setRawContent($renderer->renderRoot($render));
|
||||
|
||||
// Ensure that the exposed form is rendered.
|
||||
$this->assertEqual(1, count($this->xpath('//form[@class="views-exposed-form"]')));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ use Symfony\Component\HttpFoundation\Response;
|
|||
* @group views
|
||||
* @see \Drupal\views\ViewExecutable
|
||||
*/
|
||||
class ViewExecutableTest extends ViewUnitTestBase {
|
||||
class ViewExecutableTest extends ViewKernelTestBase {
|
||||
|
||||
use CommentTestTrait;
|
||||
|
||||
|
|
153
core/modules/views/src/Tests/ViewKernelTestBase.php
Normal file
153
core/modules/views/src/Tests/ViewKernelTestBase.php
Normal file
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\views\Tests\ViewKernelTestBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\ViewsBundle;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Defines a base class for Views unit testing.
|
||||
*
|
||||
* Use this test class for unit tests of Views functionality. If a test
|
||||
* requires the full web test environment provided by WebTestBase, extend
|
||||
* ViewTestBase instead.
|
||||
*
|
||||
* @see \Drupal\views\Tests\ViewTestBase
|
||||
*/
|
||||
abstract class ViewKernelTestBase extends KernelTestBase {
|
||||
|
||||
use ViewResultAssertionTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'views', 'views_test_config', 'views_test_data', 'user');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param bool $import_test_views
|
||||
* Should the views specififed on the test class be imported. If you need
|
||||
* to setup some additional stuff, like fields, you need to call false and
|
||||
* then call createTestViews for your own.
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp();
|
||||
|
||||
$this->installSchema('system', array('router', 'sequences'));
|
||||
$this->setUpFixtures();
|
||||
|
||||
if ($import_test_views) {
|
||||
ViewTestData::createTestViews(get_class($this), array('views_test_config'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the configuration and schema of views and views_test_data modules.
|
||||
*
|
||||
* Because the schema of views_test_data.module is dependent on the test
|
||||
* using it, it cannot be enabled normally.
|
||||
*/
|
||||
protected function setUpFixtures() {
|
||||
// First install the system module. Many Views have Page displays have menu
|
||||
// links, and for those to work, the system menus must already be present.
|
||||
$this->installConfig(array('system'));
|
||||
|
||||
// Define the schema and views data variable before enabling the test module.
|
||||
\Drupal::state()->set('views_test_data_schema', $this->schemaDefinition());
|
||||
\Drupal::state()->set('views_test_data_views_data', $this->viewsData());
|
||||
|
||||
$this->installConfig(array('views', 'views_test_config', 'views_test_data'));
|
||||
foreach ($this->schemaDefinition() as $table => $schema) {
|
||||
$this->installSchema('views_test_data', $table);
|
||||
}
|
||||
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
// Load the test dataset.
|
||||
$data_set = $this->dataSet();
|
||||
$query = db_insert('views_test_data')
|
||||
->fields(array_keys($data_set[0]));
|
||||
foreach ($data_set as $record) {
|
||||
$query->values($record);
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
protected function orderResultSet($result_set, $column, $reverse = FALSE) {
|
||||
$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);
|
||||
});
|
||||
return $result_set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a view with debugging.
|
||||
*
|
||||
* @param \Drupal\views\ViewExecutable $view
|
||||
* The view object.
|
||||
* @param array $args
|
||||
* (optional) An array of the view arguments to use for the view.
|
||||
*/
|
||||
protected function executeView($view, array $args = array()) {
|
||||
$view->setDisplay();
|
||||
$view->preExecute($args);
|
||||
$view->execute();
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the schema definition.
|
||||
*/
|
||||
protected function schemaDefinition() {
|
||||
return ViewTestData::schemaDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the views data definition.
|
||||
*/
|
||||
protected function viewsData() {
|
||||
return ViewTestData::viewsData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a very simple test dataset.
|
||||
*/
|
||||
protected function dataSet() {
|
||||
return ViewTestData::dataSet();
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,7 @@ use Drupal\views\Views;
|
|||
* @see \Drupal\views\Entity\View
|
||||
* @see \Drupal\Core\Config\Entity\ConfigEntityStorage
|
||||
*/
|
||||
class ViewStorageTest extends ViewUnitTestBase {
|
||||
class ViewStorageTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Properties that should be stored in the configuration.
|
||||
|
|
|
@ -15,10 +15,10 @@ use Drupal\views\ViewExecutable;
|
|||
* 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
|
||||
* When possible, ViewKernelTestBase should be used instead. Both base classes
|
||||
* include the same methods.
|
||||
*
|
||||
* @see \Drupal\views\Tests\ViewUnitTestBase
|
||||
* @see \Drupal\views\Tests\ViewKernelTestBase
|
||||
* @see \Drupal\simpletest\WebTestBase
|
||||
*/
|
||||
abstract class ViewTestBase extends WebTestBase {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue