Update to Drupal 8.2.0. For more information, see https://www.drupal.org/project/drupal/releases/8.2.0
This commit is contained in:
parent
2f563ab520
commit
f1c8716f57
1732 changed files with 52334 additions and 11780 deletions
0
core/modules/system/tests/fixtures/IgnoreDirectories/a.txt
vendored
Normal file
0
core/modules/system/tests/fixtures/IgnoreDirectories/a.txt
vendored
Normal file
0
core/modules/system/tests/fixtures/IgnoreDirectories/frontend_framework/b.txt
vendored
Normal file
0
core/modules/system/tests/fixtures/IgnoreDirectories/frontend_framework/b.txt
vendored
Normal file
|
@ -6,8 +6,8 @@
|
|||
* upgrade path of https://www.drupal.org/node/2354889.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
|
|
37
core/modules/system/tests/fixtures/update/drupal-8.config-override-fix.php
vendored
Normal file
37
core/modules/system/tests/fixtures/update/drupal-8.config-override-fix.php
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Partial database to create broken config overrides.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Update\ConfigOverridesUpdateTest
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Install the incorrect override configuration.
|
||||
$configs = [
|
||||
// The view has field titles translated and had an addition field added,
|
||||
// translated and then removed.
|
||||
'views.view.content',
|
||||
// The configuration has a bogus key.
|
||||
'system.cron',
|
||||
];
|
||||
foreach ($configs as $config_name) {
|
||||
$config = Yaml::parse(file_get_contents(__DIR__ . '/es-' . $config_name . '.yml'));
|
||||
$connection->delete('config')
|
||||
->condition('name', $config_name)
|
||||
->condition('collection', 'language.es')
|
||||
->execute();
|
||||
$connection->insert('config')
|
||||
->fields(['data', 'name', 'collection'])
|
||||
->values([
|
||||
'name' => $config_name,
|
||||
'data' => serialize($config),
|
||||
'collection' => 'language.es',
|
||||
])
|
||||
->execute();
|
||||
}
|
|
@ -6,8 +6,8 @@
|
|||
* upgrade path of https://www.drupal.org/node/507488.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* upgrade path of https://www.drupal.org/node/2476947.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* upgrade path of https://www.drupal.org/node/507488.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* upgrade path of https://www.drupal.org/node/2005546.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* upgrade path of https://www.drupal.org/node/2455125.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
|
@ -17,16 +17,16 @@ $views_configs = [];
|
|||
$views_configs[] = Yaml::decode(file_get_contents(__DIR__ . '/drupal-8.views-entity-views-data-2455125.yml'));
|
||||
|
||||
foreach ($views_configs as $views_config) {
|
||||
$connection->insert('config')
|
||||
->fields(array(
|
||||
$connection->insert('config')
|
||||
->fields(array(
|
||||
'collection',
|
||||
'name',
|
||||
'data',
|
||||
))
|
||||
->values(array(
|
||||
->values(array(
|
||||
'collection' => '',
|
||||
'name' => 'views.view.' . $views_config['id'],
|
||||
'data' => serialize($views_config),
|
||||
))
|
||||
->execute();
|
||||
->execute();
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* the upgrade path of https://www.drupal.org/node/2649914.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
|
|
1
core/modules/system/tests/fixtures/update/es-system.cron.yml
vendored
Normal file
1
core/modules/system/tests/fixtures/update/es-system.cron.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
bogus_key: 'Should be cleaned by system_update_8200'
|
15
core/modules/system/tests/fixtures/update/es-views.view.content.yml
vendored
Normal file
15
core/modules/system/tests/fixtures/update/es-views.view.content.yml
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
label: 'Spanish Content'
|
||||
description: 'Spanish Find and manage content.'
|
||||
display:
|
||||
default:
|
||||
display_options:
|
||||
fields:
|
||||
title:
|
||||
label: 'Spanish Title'
|
||||
name:
|
||||
label: 'Spanish Author'
|
||||
nid:
|
||||
label: 'Spanish ID'
|
||||
display_title: 'Spanish Master'
|
||||
page_1:
|
||||
display_title: 'Spanish Page'
|
|
@ -35,12 +35,17 @@ ajax_test.render:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
ajax_test.admin.theme:
|
||||
path: '/admin/ajax-test/theme'
|
||||
defaults:
|
||||
_controller: '\Drupal\ajax_test\Controller\AjaxTestController::theme'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
ajax_test.order:
|
||||
path: '/ajax-test/order'
|
||||
defaults:
|
||||
_controller: '\Drupal\ajax_test\Controller\AjaxTestController::order'
|
||||
options:
|
||||
_theme: ajax_base_page
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
|
|
|
@ -61,6 +61,15 @@ class AjaxTestController {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the used theme.
|
||||
*/
|
||||
public function theme() {
|
||||
return [
|
||||
'#markup' => 'Current theme: ' . \Drupal::theme()->getActiveTheme()->getName(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an AjaxResponse; settings command set last.
|
||||
*
|
||||
|
@ -184,6 +193,17 @@ class AjaxTestController {
|
|||
))
|
||||
),
|
||||
),
|
||||
'link8' => [
|
||||
'title' => 'Link 8 (ajax)',
|
||||
'url' => Url::fromRoute('ajax_test.admin.theme'),
|
||||
'attributes' => [
|
||||
'class' => ['use-ajax'],
|
||||
'data-dialog-type' => 'modal',
|
||||
'data-dialog-options' => json_encode([
|
||||
'width' => 400,
|
||||
]),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -46,19 +46,19 @@ class JsonRenderer implements MainContentRendererInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) {
|
||||
$json = [];
|
||||
$json = [];
|
||||
|
||||
$json['content'] = (string) $this->renderer->renderRoot($main_content);
|
||||
if (!empty($main_content['#title'])) {
|
||||
$json['title'] = (string) $main_content['#title'];
|
||||
}
|
||||
else {
|
||||
$json['title'] = (string) $this->titleResolver->getTitle($request, $route_match->getRouteObject());
|
||||
}
|
||||
$json['content'] = (string) $this->renderer->renderRoot($main_content);
|
||||
if (!empty($main_content['#title'])) {
|
||||
$json['title'] = (string) $main_content['#title'];
|
||||
}
|
||||
else {
|
||||
$json['title'] = (string) $this->titleResolver->getTitle($request, $route_match->getRouteObject());
|
||||
}
|
||||
|
||||
$response = new CacheableJsonResponse($json, 200);
|
||||
$response->addCacheableDependency(CacheableMetadata::createFromRenderArray($main_content));
|
||||
return $response;
|
||||
$response = new CacheableJsonResponse($json, 200);
|
||||
$response->addCacheableDependency(CacheableMetadata::createFromRenderArray($main_content));
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\condition_test\Tests;
|
||||
|
||||
use Drupal\Core\Plugin\Context\Context;
|
||||
use Drupal\Core\Plugin\Context\ContextDefinition;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Tests a condition that requires two users.
|
||||
*
|
||||
* @group condition_test
|
||||
*/
|
||||
class ConditionTestDualUserTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* An anonymous user for testing purposes.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $anonymous;
|
||||
|
||||
/**
|
||||
* An authenticated user for testing purposes.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $authenticated;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'user', 'condition_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installSchema('system', 'sequences');
|
||||
$this->installEntitySchema('user');
|
||||
|
||||
$this->anonymous = User::create(['uid' => 0]);
|
||||
$this->authenticated = User::create(['uid' => 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the dual user condition.
|
||||
*/
|
||||
public function testConditions() {
|
||||
$this->doTestIdenticalUser();
|
||||
$this->doTestDifferentUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests with both contexts mapped to the same user.
|
||||
*/
|
||||
protected function doTestIdenticalUser() {
|
||||
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
|
||||
$condition = \Drupal::service('plugin.manager.condition')
|
||||
->createInstance('condition_test_dual_user')
|
||||
// Map the anonymous user to both contexts.
|
||||
->setContextMapping([
|
||||
'user1' => 'anonymous',
|
||||
'user2' => 'anonymous',
|
||||
]);
|
||||
$definition = new ContextDefinition('entity:user');
|
||||
$contexts['anonymous'] = new Context($definition, $this->anonymous);
|
||||
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
|
||||
$this->assertTrue($condition->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests with each context mapped to different users.
|
||||
*/
|
||||
protected function doTestDifferentUser() {
|
||||
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
|
||||
$condition = \Drupal::service('plugin.manager.condition')
|
||||
->createInstance('condition_test_dual_user')
|
||||
->setContextMapping([
|
||||
'user1' => 'anonymous',
|
||||
'user2' => 'authenticated',
|
||||
]);
|
||||
$definition = new ContextDefinition('entity:user');
|
||||
$contexts['anonymous'] = new Context($definition, $this->anonymous);
|
||||
$contexts['authenticated'] = new Context($definition, $this->authenticated);
|
||||
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
|
||||
$this->assertFalse($condition->execute());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\condition_test\Tests;
|
||||
|
||||
use Drupal\Core\Plugin\Context\Context;
|
||||
use Drupal\Core\Plugin\Context\ContextDefinition;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests a condition with optional context.
|
||||
*
|
||||
* @group condition_test
|
||||
*/
|
||||
class OptionalContextConditionTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'user', 'condition_test', 'node'];
|
||||
|
||||
/**
|
||||
* Tests with both contexts mapped to the same user.
|
||||
*/
|
||||
protected function testContextMissing() {
|
||||
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
|
||||
$condition = \Drupal::service('plugin.manager.condition')
|
||||
->createInstance('condition_test_optional_context')
|
||||
->setContextMapping([
|
||||
'node' => 'node',
|
||||
]);
|
||||
\Drupal::service('context.handler')->applyContextMapping($condition, []);
|
||||
$this->assertTrue($condition->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests with both contexts mapped to the same user.
|
||||
*/
|
||||
protected function testContextNoValue() {
|
||||
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
|
||||
$condition = \Drupal::service('plugin.manager.condition')
|
||||
->createInstance('condition_test_optional_context')
|
||||
->setContextMapping([
|
||||
'node' => 'node',
|
||||
]);
|
||||
$definition = new ContextDefinition('entity:node');
|
||||
$contexts['node'] = (new Context($definition));
|
||||
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
|
||||
$this->assertTrue($condition->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests with both contexts mapped to the same user.
|
||||
*/
|
||||
protected function testContextAvailable() {
|
||||
NodeType::create(['type' => 'example', 'name' => 'Example'])->save();
|
||||
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
|
||||
$condition = \Drupal::service('plugin.manager.condition')
|
||||
->createInstance('condition_test_optional_context')
|
||||
->setContextMapping([
|
||||
'node' => 'node',
|
||||
]);
|
||||
$definition = new ContextDefinition('entity:node');
|
||||
$node = Node::create(['type' => 'example']);
|
||||
$contexts['node'] = new Context($definition, $node);
|
||||
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
|
||||
$this->assertFalse($condition->execute());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
name: CSRF test
|
||||
type: module
|
||||
description: 'Support testing protecting routes with CSRF token.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
|
@ -0,0 +1,27 @@
|
|||
# Tests CSRF request header token protection.
|
||||
csrf_test.protected:
|
||||
path: csrf/protected
|
||||
defaults:
|
||||
_controller: '\Drupal\csrf_test\Controller\TestController::testMethod'
|
||||
requirements:
|
||||
_csrf_request_header_token: 'TRUE'
|
||||
_method: 'POST'
|
||||
# Tests deprecated _access_rest_csrf protection.
|
||||
# This originally was in the REST module but now is supported in core/lib.
|
||||
# @see https://www.drupal.org/node/2753681
|
||||
# @todo Remove this test route in Drupal 9.0.0.
|
||||
csrf_test.deprecated.protected:
|
||||
path: csrf/deprecated/protected
|
||||
defaults:
|
||||
_controller: '\Drupal\csrf_test\Controller\TestController::testMethod'
|
||||
requirements:
|
||||
_access_rest_csrf: 'TRUE'
|
||||
_method: 'POST'
|
||||
# @todo This route can be removed in 8.3.
|
||||
# @see \Drupal\Core\Access\CsrfRequestHeaderAccessCheck::access()
|
||||
csrf_test.deprecated.csrftoken:
|
||||
path: '/deprecated/session/token'
|
||||
defaults:
|
||||
_controller: '\Drupal\csrf_test\Controller\DeprecatedCsrfTokenController::csrfToken'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\csrf_test\Controller;
|
||||
|
||||
use Drupal\Core\Access\CsrfTokenGenerator;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Returns responses for Deprecated CSRF token routes.
|
||||
*
|
||||
* This controller tests using the deprecated CSRF token key 'rest'.
|
||||
*
|
||||
* @todo This class can be removed in 8.3.
|
||||
*
|
||||
* @see \Drupal\Core\Access\CsrfRequestHeaderAccessCheck::access()
|
||||
*/
|
||||
class DeprecatedCsrfTokenController implements ContainerInjectionInterface {
|
||||
|
||||
/**
|
||||
* The CSRF token generator.
|
||||
*
|
||||
* @var \Drupal\Core\Access\CsrfTokenGenerator
|
||||
*/
|
||||
protected $tokenGenerator;
|
||||
|
||||
/**
|
||||
* Constructs a new CsrfTokenController object.
|
||||
*
|
||||
* @param \Drupal\Core\Access\CsrfTokenGenerator $token_generator
|
||||
* The CSRF token generator.
|
||||
*/
|
||||
public function __construct(CsrfTokenGenerator $token_generator) {
|
||||
$this->tokenGenerator = $token_generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('csrf_token')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a CSRF using the deprecated 'rest' value protecting session token.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* The response object.
|
||||
*/
|
||||
public function csrfToken() {
|
||||
return new Response($this->tokenGenerator->get('rest'), 200, ['Content-Type' => 'text/plain']);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\csrf_test\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Just a test controller for test routes.
|
||||
*/
|
||||
class TestController {
|
||||
|
||||
/**
|
||||
* Just a test method for the test routes.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* The response object.
|
||||
*/
|
||||
public function testMethod() {
|
||||
return new Response('Sometimes it is hard to think of test content!');
|
||||
}
|
||||
|
||||
}
|
|
@ -3,28 +3,10 @@
|
|||
namespace Drupal\early_rendering_controller_test;
|
||||
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Cache\UncacheableDependencyTrait;
|
||||
|
||||
class CacheableTestDomainObject extends TestDomainObject implements CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheTags() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return 0;
|
||||
}
|
||||
use UncacheableDependencyTrait;
|
||||
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ display:
|
|||
entity_field: title
|
||||
filters:
|
||||
status:
|
||||
value: true
|
||||
value: '1'
|
||||
table: node_field_data
|
||||
field: status
|
||||
id: status
|
||||
|
|
|
@ -325,7 +325,11 @@ function entity_test_form_node_form_alter(&$form, FormStateInterface $form_state
|
|||
* The loaded entity object, or NULL if the entity cannot be loaded.
|
||||
*/
|
||||
function entity_test_load($id, $reset = FALSE) {
|
||||
return entity_load('entity_test', $id, $reset);
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test');
|
||||
if ($reset) {
|
||||
$storage->resetCache([$id]);
|
||||
}
|
||||
return $storage->load($id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -340,7 +344,11 @@ function entity_test_load($id, $reset = FALSE) {
|
|||
* The loaded entity object, or NULL if the entity cannot be loaded.
|
||||
*/
|
||||
function entity_test_rev_load($id, $reset = FALSE) {
|
||||
return entity_load('entity_test_rev', $id, $reset);
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_rev');
|
||||
if ($reset) {
|
||||
$storage->resetCache([$id]);
|
||||
}
|
||||
return $storage->load($id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -355,7 +363,11 @@ function entity_test_rev_load($id, $reset = FALSE) {
|
|||
* The loaded entity object, or FALSE if the entity cannot be loaded.
|
||||
*/
|
||||
function entity_test_mul_load($id, $reset = FALSE) {
|
||||
return entity_load('entity_test_mul', $id, $reset);
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_mul');
|
||||
if ($reset) {
|
||||
$storage->resetCache([$id]);
|
||||
}
|
||||
return $storage->load($id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -370,7 +382,11 @@ function entity_test_mul_load($id, $reset = FALSE) {
|
|||
* The loaded entity object, or NULL if the entity cannot be loaded.
|
||||
*/
|
||||
function entity_test_mulrev_load($id, $reset = FALSE) {
|
||||
return entity_load('entity_test_mulrev', $id, $reset);
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev');
|
||||
if ($reset) {
|
||||
$storage->resetCache([$id]);
|
||||
}
|
||||
return $storage->load($id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,7 +22,7 @@ class EntityTestController extends ControllerBase {
|
|||
/**
|
||||
* Constructs a new EntityTestController.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\Query\QueryFactory
|
||||
* @param \Drupal\Core\Entity\Query\QueryFactory $entity_query_factory
|
||||
* The entity query factory.
|
||||
*/
|
||||
public function __construct(QueryFactory $entity_query_factory) {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
|
||||
/**
|
||||
* Defines the test entity class.
|
||||
*
|
||||
* @ContentEntityType(
|
||||
* id = "entity_test_field_methods",
|
||||
* label = @Translation("Test entity - data table"),
|
||||
* handlers = {
|
||||
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
|
||||
* "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
|
||||
* "form" = {
|
||||
* "default" = "Drupal\entity_test\EntityTestForm",
|
||||
* "delete" = "Drupal\entity_test\EntityTestDeleteForm"
|
||||
* },
|
||||
* "translation" = "Drupal\content_translation\ContentTranslationHandler",
|
||||
* "views_data" = "Drupal\views\EntityViewsData",
|
||||
* "route_provider" = {
|
||||
* "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
|
||||
* },
|
||||
* },
|
||||
* base_table = "entity_test_field_methods",
|
||||
* data_table = "entity_test_field_methods_property",
|
||||
* admin_permission = "administer entity_test content",
|
||||
* translatable = TRUE,
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "uuid" = "uuid",
|
||||
* "bundle" = "type",
|
||||
* "label" = "name",
|
||||
* "langcode" = "langcode",
|
||||
* },
|
||||
* )
|
||||
*/
|
||||
class EntityTestFieldMethods extends EntityTestMul {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields = parent::baseFieldDefinitions($entity_type);
|
||||
|
||||
$fields['test_invocation_order'] = BaseFieldDefinition::create('auto_incrementing_test')
|
||||
->setLabel(t('Test field method invocation order.'))
|
||||
->setTranslatable(TRUE);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
|
@ -67,6 +67,7 @@ class EntityTestRev extends EntityTest {
|
|||
->setLabel(t('Non Revisionable Field'))
|
||||
->setDescription(t('A non-revisionable test field.'))
|
||||
->setRevisionable(FALSE)
|
||||
->setTranslatable(TRUE)
|
||||
->setCardinality(1)
|
||||
->setReadOnly(TRUE);
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\entity_test\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem;
|
||||
|
||||
/**
|
||||
* Defines the 'field_method_invocation_order_test' entity field type.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "auto_incrementing_test",
|
||||
* label = @Translation("Auto incrementing test field item"),
|
||||
* description = @Translation("An entity field designed to test the field method invocation order."),
|
||||
* category = @Translation("Number"),
|
||||
* no_ui = TRUE,
|
||||
* )
|
||||
*/
|
||||
class AutoIncrementingTestItem extends IntegerItem {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave() {
|
||||
parent::preSave();
|
||||
$this->value = static::getIncrementedFieldValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an incremented field value.
|
||||
*
|
||||
* @return int
|
||||
* The incremented field value.
|
||||
*/
|
||||
private static function getIncrementedFieldValue() {
|
||||
$current_value = &drupal_static(__METHOD__, 0);
|
||||
return ++$current_value;
|
||||
}
|
||||
|
||||
}
|
|
@ -418,10 +418,11 @@ form_test.description_display:
|
|||
_access: 'TRUE'
|
||||
|
||||
form_test.group_details:
|
||||
path: '/form-test/group-details'
|
||||
path: '/form-test/group-details/{required}'
|
||||
defaults:
|
||||
_form: '\Drupal\form_test\Form\FormTestGroupDetailsForm'
|
||||
_title: 'Group details testing'
|
||||
required: FALSE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
|
@ -434,10 +435,11 @@ form_test.group_container:
|
|||
_access: 'TRUE'
|
||||
|
||||
form_test.group_fieldset:
|
||||
path: '/form-test/group-fieldset'
|
||||
path: '/form-test/group-fieldset/{required}'
|
||||
defaults:
|
||||
_form: '\Drupal\form_test\Form\FormTestGroupFieldsetForm'
|
||||
_title: 'Group fieldset testing'
|
||||
required: FALSE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
|
|
|
@ -20,11 +20,12 @@ class FormTestGroupDetailsForm extends FormBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
public function buildForm(array $form, FormStateInterface $form_state, $required = FALSE) {
|
||||
$form['details'] = array(
|
||||
'#type' => 'details',
|
||||
'#title' => 'Root element',
|
||||
'#open' => TRUE,
|
||||
'#required' => !empty($required),
|
||||
);
|
||||
$form['meta'] = array(
|
||||
'#type' => 'details',
|
||||
|
|
|
@ -20,10 +20,11 @@ class FormTestGroupFieldsetForm extends FormBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
public function buildForm(array $form, FormStateInterface $form_state, $required = FALSE) {
|
||||
$form['fieldset'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => 'Fieldset',
|
||||
'#required' => !empty($required),
|
||||
);
|
||||
$form['meta'] = array(
|
||||
'#type' => 'container',
|
||||
|
|
|
@ -10,12 +10,12 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
|||
*/
|
||||
class TestMiddleware implements HttpKernelInterface {
|
||||
|
||||
/**
|
||||
* The decorated kernel.
|
||||
*
|
||||
* @var \Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
*/
|
||||
protected $kernel;
|
||||
/**
|
||||
* The decorated kernel.
|
||||
*
|
||||
* @var \Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
*/
|
||||
protected $kernel;
|
||||
|
||||
/**
|
||||
* An optional argument.
|
||||
|
@ -35,21 +35,21 @@ class TestMiddleware implements HttpKernelInterface {
|
|||
public function __construct(HttpKernelInterface $kernel, $optional_argument = NULL) {
|
||||
$this->kernel = $kernel;
|
||||
$this->optionalArgument = $optional_argument;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
|
||||
$request->attributes->set('_hello', 'world');
|
||||
if ($request->attributes->has('_optional_argument')) {
|
||||
$request->attributes->set('_previous_optional_argument', $request->attributes->get('_optional_argument'));
|
||||
}
|
||||
elseif (isset($this->optionalArgument)) {
|
||||
$request->attributes->set('_optional_argument', $this->optionalArgument);
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
|
||||
$request->attributes->set('_hello', 'world');
|
||||
if ($request->attributes->has('_optional_argument')) {
|
||||
$request->attributes->set('_previous_optional_argument', $request->attributes->get('_optional_argument'));
|
||||
}
|
||||
elseif (isset($this->optionalArgument)) {
|
||||
$request->attributes->set('_optional_argument', $this->optionalArgument);
|
||||
}
|
||||
|
||||
return $this->kernel->handle($request, $type, $catch);
|
||||
}
|
||||
return $this->kernel->handle($request, $type, $catch);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
name: 'Module install class loader test1'
|
||||
description: 'Support module for tests that the class loader behaves as expected during module install.'
|
||||
type: module
|
||||
package: Testing
|
||||
core: 8.x
|
||||
version: VERSION
|
|
@ -0,0 +1,5 @@
|
|||
services:
|
||||
module_install_class_loader_test1.event_subscriber:
|
||||
class: Drupal\module_install_class_loader_test1\EventSubscriber
|
||||
tags:
|
||||
- { name: event_subscriber }
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\module_install_class_loader_test1;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* An event subscriber that does different things depending on whether classes
|
||||
* exist.
|
||||
*/
|
||||
class EventSubscriber implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
$events = [];
|
||||
// If the autoloader is not fixed during module install when the modules
|
||||
// module_install_class_loader_test1 and module_install_class_loader_test2
|
||||
// are enabled in the same request the class_exists() will cause a crash.
|
||||
// This is because \Composer\Autoload\ClassLoader maintains a negative
|
||||
// cache.
|
||||
if (class_exists('\Drupal\module_install_class_loader_test2\EventSubscriber')) {
|
||||
$events = [];
|
||||
}
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
name: 'Module install class loader test2'
|
||||
description: 'Support module for tests that the class loader behaves as expected during module install.'
|
||||
type: module
|
||||
package: Testing
|
||||
core: 8.x
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- module_install_class_loader_test1
|
|
@ -0,0 +1,5 @@
|
|||
services:
|
||||
module_install_class_loader_test1.event_subscriber:
|
||||
class: Drupal\module_install_class_loader_test2\EventSubscriber
|
||||
tags:
|
||||
- { name: event_subscriber }
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\module_install_class_loader_test2;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* An event subscriber that does nothing.
|
||||
*/
|
||||
class EventSubscriber implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
|
@ -12,12 +12,12 @@ use Drupal\Core\Plugin\DefaultPluginManager;
|
|||
*/
|
||||
class DefaultsTestPluginManager extends DefaultPluginManager {
|
||||
|
||||
/**
|
||||
* Constructs a new DefaultsTestPluginManager instance.
|
||||
*
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
*/
|
||||
/**
|
||||
* Constructs a new DefaultsTestPluginManager instance.
|
||||
*
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
*/
|
||||
public function __construct(ModuleHandlerInterface $module_handler) {
|
||||
// Create the object that can be used to return definitions for all the
|
||||
// plugins available for this type. Most real plugin managers use a richer
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\plugin_test\Plugin\plugin_test\fruit;
|
||||
|
||||
use Drupal\non_installed_module\Plugin\plugin_test\fruit\YummyFruit;
|
||||
|
||||
/**
|
||||
* @Plugin(
|
||||
* id = "extending_non_installed_class",
|
||||
* label = "A plugin whose class is extending from a non-installed module class",
|
||||
* color = "pink",
|
||||
* )
|
||||
*/
|
||||
class ExtendingNonInstalledClass extends YummyFruit { }
|
|
@ -348,4 +348,16 @@ class SystemTestController extends ControllerBase {
|
|||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a response with a test header set from the request.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response $response
|
||||
* A Response object containing the test header.
|
||||
*/
|
||||
public function getTestHeader(Request $request) {
|
||||
$response = new Response();
|
||||
$response->headers->set('Test-Header', $request->headers->get('Test-Header'));
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -175,3 +175,10 @@ system_test.always_denied:
|
|||
_controller: 'chop'
|
||||
requirements:
|
||||
_access: 'FALSE'
|
||||
|
||||
system_test.header:
|
||||
path: '/system-test/header'
|
||||
defaults:
|
||||
_controller: '\Drupal\system_test\Controller\SystemTestController::getTestHeader'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -88,4 +88,14 @@ class Test {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a page with encoded markup.
|
||||
*
|
||||
* @return array
|
||||
* A render array as expected by drupal_render()
|
||||
*/
|
||||
public function renderEncodedMarkup() {
|
||||
return ['#plain_text' => 'Bad html <script>alert(123);</script>'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,9 +11,10 @@ class TestPageTestController {
|
|||
* Returns a test page and sets the title.
|
||||
*/
|
||||
public function testPage() {
|
||||
$link_text = t('Visually identical test links');
|
||||
return [
|
||||
'#title' => t('Test page'),
|
||||
'#markup' => t('Test page text.'),
|
||||
'#markup' => t('Test page text.') . "<a href=\"/user/login\">$link_text</a><a href=\"/user/register\">$link_text</a>",
|
||||
'#attached' => [
|
||||
'drupalSettings' => [
|
||||
'test-setting' => 'azAZ09();.,\\\/-_{}',
|
||||
|
|
|
@ -58,3 +58,11 @@ test_page_test.error:
|
|||
code: 200
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
test_page_test.encoded:
|
||||
path: '/test-encoded'
|
||||
defaults:
|
||||
_title: 'Page with encoded HTML'
|
||||
_controller: '\Drupal\test_page_test\Controller\Test::renderEncodedMarkup'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
|
||||
/**
|
||||
* Tests protecting routes by requiring CSRF token in the request header.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class CsrfRequestHeaderTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system', 'csrf_test'];
|
||||
|
||||
/**
|
||||
* Tests access to routes protected by CSRF request header requirements.
|
||||
*
|
||||
* This checks one route that uses _csrf_request_header_token and one that
|
||||
* uses the deprecated _access_rest_csrf.
|
||||
*/
|
||||
public function testRouteAccess() {
|
||||
$client = \Drupal::httpClient();
|
||||
$csrf_token_paths = ['deprecated/session/token', 'session/token'];
|
||||
// Test using the both the current path and a test path that returns
|
||||
// a token using the deprecated 'rest' value.
|
||||
// Checking /deprecated/session/token can be removed in 8.3.
|
||||
// @see \Drupal\Core\Access\CsrfRequestHeaderAccessCheck::access()
|
||||
foreach ($csrf_token_paths as $csrf_token_path) {
|
||||
// Check both test routes.
|
||||
$route_names = ['csrf_test.protected', 'csrf_test.deprecated.protected'];
|
||||
foreach ($route_names as $route_name) {
|
||||
$user = $this->drupalCreateUser();
|
||||
$this->drupalLogin($user);
|
||||
|
||||
$csrf_token = $this->drupalGet($csrf_token_path);
|
||||
$url = Url::fromRoute($route_name)
|
||||
->setAbsolute(TRUE)
|
||||
->toString();
|
||||
$domain = parse_url($url, PHP_URL_HOST);
|
||||
|
||||
$session_id = $this->getSession()->getCookie($this->getSessionName());
|
||||
/** @var \GuzzleHttp\Cookie\CookieJar $cookies */
|
||||
$cookies = CookieJar::fromArray([$this->getSessionName() => $session_id], $domain);
|
||||
$post_options = [
|
||||
'headers' => ['Accept' => 'text/plain'],
|
||||
'http_errors' => FALSE,
|
||||
];
|
||||
|
||||
// Test that access is allowed for anonymous user with no token in header.
|
||||
$result = $client->post($url, $post_options);
|
||||
$this->assertEquals(200, $result->getStatusCode());
|
||||
|
||||
// Add cookies to POST options so that all other requests are for the
|
||||
// authenticated user.
|
||||
$post_options['cookies'] = $cookies;
|
||||
|
||||
// Test that access is denied with no token in header.
|
||||
$result = $client->post($url, $post_options);
|
||||
$this->assertEquals(403, $result->getStatusCode());
|
||||
|
||||
// Test that access is allowed with correct token in header.
|
||||
$post_options['headers']['X-CSRF-Token'] = $csrf_token;
|
||||
$result = $client->post($url, $post_options);
|
||||
$this->assertEquals(200, $result->getStatusCode());
|
||||
|
||||
// Test that access is denied with incorrect token in header.
|
||||
$post_options['headers']['X-CSRF-Token'] = 'this-is-not-the-token-you-are-looking-for';
|
||||
$result = $client->post($url, $post_options);
|
||||
$this->assertEquals(403, $result->getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
101
core/modules/system/tests/src/Kernel/Action/ActionTest.php
Normal file
101
core/modules/system/tests/src/Kernel/Action/ActionTest.php
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\system\Entity\Action;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* Tests action plugins.
|
||||
*
|
||||
* @group Action
|
||||
*/
|
||||
class ActionTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = array('system', 'field', 'user', 'action_test');
|
||||
|
||||
/**
|
||||
* The action manager.
|
||||
*
|
||||
* @var \Drupal\Core\Action\ActionManager
|
||||
*/
|
||||
protected $actionManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->actionManager = $this->container->get('plugin.manager.action');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installSchema('system', array('sequences'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the functionality of test actions.
|
||||
*/
|
||||
public function testOperations() {
|
||||
// Test that actions can be discovered.
|
||||
$definitions = $this->actionManager->getDefinitions();
|
||||
$this->assertTrue(count($definitions) > 1, 'Action definitions are found.');
|
||||
$this->assertTrue(!empty($definitions['action_test_no_type']), 'The test action is among the definitions found.');
|
||||
|
||||
$definition = $this->actionManager->getDefinition('action_test_no_type');
|
||||
$this->assertTrue(!empty($definition), 'The test action definition is found.');
|
||||
|
||||
$definitions = $this->actionManager->getDefinitionsByType('user');
|
||||
$this->assertTrue(empty($definitions['action_test_no_type']), 'An action with no type is not found.');
|
||||
|
||||
// Create an instance of the 'save entity' action.
|
||||
$action = $this->actionManager->createInstance('action_test_save_entity');
|
||||
$this->assertTrue($action instanceof ActionInterface, 'The action implements the correct interface.');
|
||||
|
||||
// Create a new unsaved user.
|
||||
$name = $this->randomMachineName();
|
||||
$user_storage = $this->container->get('entity.manager')->getStorage('user');
|
||||
$account = $user_storage->create(array('name' => $name, 'bundle' => 'user'));
|
||||
$loaded_accounts = $user_storage->loadMultiple();
|
||||
$this->assertEqual(count($loaded_accounts), 0);
|
||||
|
||||
// Execute the 'save entity' action.
|
||||
$action->execute($account);
|
||||
$loaded_accounts = $user_storage->loadMultiple();
|
||||
$this->assertEqual(count($loaded_accounts), 1);
|
||||
$account = reset($loaded_accounts);
|
||||
$this->assertEqual($name, $account->label());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the dependency calculation of actions.
|
||||
*/
|
||||
public function testDependencies() {
|
||||
// Create a new action that depends on a user role.
|
||||
$action = Action::create(array(
|
||||
'id' => 'user_add_role_action.' . RoleInterface::ANONYMOUS_ID,
|
||||
'type' => 'user',
|
||||
'label' => t('Add the anonymous role to the selected users'),
|
||||
'configuration' => array(
|
||||
'rid' => RoleInterface::ANONYMOUS_ID,
|
||||
),
|
||||
'plugin' => 'user_add_role_action',
|
||||
));
|
||||
$action->save();
|
||||
|
||||
$expected = array(
|
||||
'config' => array(
|
||||
'user.role.' . RoleInterface::ANONYMOUS_ID,
|
||||
),
|
||||
'module' => array(
|
||||
'user',
|
||||
),
|
||||
);
|
||||
$this->assertIdentical($expected, $action->calculateDependencies()->getDependencies());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Block;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\system\Entity\Menu;
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\system\Tests\Routing\MockRouteProvider;
|
||||
use Drupal\Tests\Core\Menu\MenuLinkMock;
|
||||
use Drupal\user\Entity\User;
|
||||
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* Tests \Drupal\system\Plugin\Block\SystemMenuBlock.
|
||||
*
|
||||
* @group Block
|
||||
* @todo Expand test coverage to all SystemMenuBlock functionality, including
|
||||
* block_menu_delete().
|
||||
*
|
||||
* @see \Drupal\system\Plugin\Derivative\SystemMenuBlock
|
||||
* @see \Drupal\system\Plugin\Block\SystemMenuBlock
|
||||
*/
|
||||
class SystemMenuBlockTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array(
|
||||
'system',
|
||||
'block',
|
||||
'menu_test',
|
||||
'menu_link_content',
|
||||
'field',
|
||||
'user',
|
||||
'link',
|
||||
);
|
||||
|
||||
/**
|
||||
* The block under test.
|
||||
*
|
||||
* @var \Drupal\system\Plugin\Block\SystemMenuBlock
|
||||
*/
|
||||
protected $block;
|
||||
|
||||
/**
|
||||
* The menu for testing.
|
||||
*
|
||||
* @var \Drupal\system\MenuInterface
|
||||
*/
|
||||
protected $menu;
|
||||
|
||||
/**
|
||||
* The menu link tree service.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuLinkTree
|
||||
*/
|
||||
protected $linkTree;
|
||||
|
||||
/**
|
||||
* The menu link plugin manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager
|
||||
*/
|
||||
protected $menuLinkManager;
|
||||
|
||||
/**
|
||||
* The block manager service.
|
||||
*
|
||||
* @var \Drupal\Core\block\BlockManagerInterface
|
||||
*/
|
||||
protected $blockManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('system', 'sequences');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('menu_link_content');
|
||||
|
||||
$account = User::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'status' => 1,
|
||||
]);
|
||||
$account->save();
|
||||
$this->container->get('current_user')->setAccount($account);
|
||||
|
||||
$this->menuLinkManager = $this->container->get('plugin.manager.menu.link');
|
||||
$this->linkTree = $this->container->get('menu.link_tree');
|
||||
$this->blockManager = $this->container->get('plugin.manager.block');
|
||||
|
||||
$routes = new RouteCollection();
|
||||
$requirements = array('_access' => 'TRUE');
|
||||
$options = array('_access_checks' => array('access_check.default'));
|
||||
$routes->add('example1', new Route('/example1', array(), $requirements, $options));
|
||||
$routes->add('example2', new Route('/example2', array(), $requirements, $options));
|
||||
$routes->add('example3', new Route('/example3', array(), $requirements, $options));
|
||||
$routes->add('example4', new Route('/example4', array(), $requirements, $options));
|
||||
$routes->add('example5', new Route('/example5', array(), $requirements, $options));
|
||||
$routes->add('example6', new Route('/example6', array(), $requirements, $options));
|
||||
$routes->add('example7', new Route('/example7', array(), $requirements, $options));
|
||||
$routes->add('example8', new Route('/example8', array(), $requirements, $options));
|
||||
|
||||
$mock_route_provider = new MockRouteProvider($routes);
|
||||
$this->container->set('router.route_provider', $mock_route_provider);
|
||||
|
||||
// Add a new custom menu.
|
||||
$menu_name = 'mock';
|
||||
$label = $this->randomMachineName(16);
|
||||
|
||||
$this->menu = Menu::create(array(
|
||||
'id' => $menu_name,
|
||||
'label' => $label,
|
||||
'description' => 'Description text',
|
||||
));
|
||||
$this->menu->save();
|
||||
|
||||
// This creates a tree with the following structure:
|
||||
// - 1
|
||||
// - 2
|
||||
// - 3
|
||||
// - 4
|
||||
// - 5
|
||||
// - 7
|
||||
// - 6
|
||||
// - 8
|
||||
// With link 6 being the only external link.
|
||||
$links = array(
|
||||
1 => MenuLinkMock::create(array('id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '', 'weight' => 0)),
|
||||
2 => MenuLinkMock::create(array('id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => '', 'route_parameters' => array('foo' => 'bar'), 'weight' => 1)),
|
||||
3 => MenuLinkMock::create(array('id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'weight' => 2)),
|
||||
4 => MenuLinkMock::create(array('id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3', 'weight' => 3)),
|
||||
5 => MenuLinkMock::create(array('id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '', 'expanded' => TRUE, 'weight' => 4)),
|
||||
6 => MenuLinkMock::create(array('id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'barbar', 'parent' => '', 'weight' => 5)),
|
||||
7 => MenuLinkMock::create(array('id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => 'test.example5', 'weight' => 6)),
|
||||
8 => MenuLinkMock::create(array('id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '', 'weight' => 7)),
|
||||
);
|
||||
foreach ($links as $instance) {
|
||||
$this->menuLinkManager->addDefinition($instance->getPluginId(), $instance->getPluginDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests calculation of a system menu block's configuration dependencies.
|
||||
*/
|
||||
public function testSystemMenuBlockConfigDependencies() {
|
||||
|
||||
$block = Block::create(array(
|
||||
'plugin' => 'system_menu_block:' . $this->menu->id(),
|
||||
'region' => 'footer',
|
||||
'id' => 'machinename',
|
||||
'theme' => 'stark',
|
||||
));
|
||||
|
||||
$dependencies = $block->calculateDependencies()->getDependencies();
|
||||
$expected = array(
|
||||
'config' => array(
|
||||
'system.menu.' . $this->menu->id()
|
||||
),
|
||||
'module' => array(
|
||||
'system'
|
||||
),
|
||||
'theme' => array(
|
||||
'stark'
|
||||
),
|
||||
);
|
||||
$this->assertIdentical($expected, $dependencies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the config start level and depth.
|
||||
*/
|
||||
public function testConfigLevelDepth() {
|
||||
// Helper function to generate a configured block instance.
|
||||
$place_block = function ($level, $depth) {
|
||||
return $this->blockManager->createInstance('system_menu_block:' . $this->menu->id(), array(
|
||||
'region' => 'footer',
|
||||
'id' => 'machinename',
|
||||
'theme' => 'stark',
|
||||
'level' => $level,
|
||||
'depth' => $depth,
|
||||
));
|
||||
};
|
||||
|
||||
// All the different block instances we're going to test.
|
||||
$blocks = [
|
||||
'all' => $place_block(1, 0),
|
||||
'level_1_only' => $place_block(1, 1),
|
||||
'level_2_only' => $place_block(2, 1),
|
||||
'level_3_only' => $place_block(3, 1),
|
||||
'level_1_and_beyond' => $place_block(1, 0),
|
||||
'level_2_and_beyond' => $place_block(2, 0),
|
||||
'level_3_and_beyond' => $place_block(3, 0),
|
||||
];
|
||||
|
||||
// Scenario 1: test all block instances when there's no active trail.
|
||||
$no_active_trail_expectations = [];
|
||||
$no_active_trail_expectations['all'] = [
|
||||
'test.example1' => [],
|
||||
'test.example2' => [],
|
||||
'test.example5' => [
|
||||
'test.example7' => [],
|
||||
],
|
||||
'test.example6' => [],
|
||||
'test.example8' => [],
|
||||
];
|
||||
$no_active_trail_expectations['level_1_only'] = [
|
||||
'test.example1' => [],
|
||||
'test.example2' => [],
|
||||
'test.example5' => [],
|
||||
'test.example6' => [],
|
||||
'test.example8' => [],
|
||||
];
|
||||
$no_active_trail_expectations['level_2_only'] = [
|
||||
'test.example7' => [],
|
||||
];
|
||||
$no_active_trail_expectations['level_3_only'] = [];
|
||||
$no_active_trail_expectations['level_1_and_beyond'] = $no_active_trail_expectations['all'];
|
||||
$no_active_trail_expectations['level_2_and_beyond'] = $no_active_trail_expectations['level_2_only'];
|
||||
$no_active_trail_expectations['level_3_and_beyond'] = [];
|
||||
foreach ($blocks as $id => $block) {
|
||||
$block_build = $block->build();
|
||||
$items = isset($block_build['#items']) ? $block_build['#items'] : [];
|
||||
$this->assertIdentical($no_active_trail_expectations[$id], $this->convertBuiltMenuToIdTree($items), format_string('Menu block %id with no active trail renders the expected tree.', ['%id' => $id]));
|
||||
}
|
||||
|
||||
// Scenario 2: test all block instances when there's an active trail.
|
||||
$route = $this->container->get('router.route_provider')->getRouteByName('example3');
|
||||
$request = new Request();
|
||||
$request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'example3');
|
||||
$request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, $route);
|
||||
$this->container->get('request_stack')->push($request);
|
||||
// \Drupal\Core\Menu\MenuActiveTrail uses the cache collector pattern, which
|
||||
// includes static caching. Since this second scenario simulates a second
|
||||
// request, we must also simulate it for the MenuActiveTrail service, by
|
||||
// clearing the cache collector's static cache.
|
||||
\Drupal::service('menu.active_trail')->clear();
|
||||
|
||||
$active_trail_expectations = [];
|
||||
$active_trail_expectations['all'] = [
|
||||
'test.example1' => [],
|
||||
'test.example2' => [
|
||||
'test.example3' => [
|
||||
'test.example4' => [],
|
||||
]
|
||||
],
|
||||
'test.example5' => [
|
||||
'test.example7' => [],
|
||||
],
|
||||
'test.example6' => [],
|
||||
'test.example8' => [],
|
||||
];
|
||||
$active_trail_expectations['level_1_only'] = [
|
||||
'test.example1' => [],
|
||||
'test.example2' => [],
|
||||
'test.example5' => [],
|
||||
'test.example6' => [],
|
||||
'test.example8' => [],
|
||||
];
|
||||
$active_trail_expectations['level_2_only'] = [
|
||||
'test.example3' => [],
|
||||
'test.example7' => [],
|
||||
];
|
||||
$active_trail_expectations['level_3_only'] = [
|
||||
'test.example4' => [],
|
||||
];
|
||||
$active_trail_expectations['level_1_and_beyond'] = $active_trail_expectations['all'];
|
||||
$active_trail_expectations['level_2_and_beyond'] = [
|
||||
'test.example3' => [
|
||||
'test.example4' => [],
|
||||
],
|
||||
'test.example7' => [],
|
||||
];
|
||||
$active_trail_expectations['level_3_and_beyond'] = $active_trail_expectations['level_3_only'];
|
||||
foreach ($blocks as $id => $block) {
|
||||
$block_build = $block->build();
|
||||
$items = isset($block_build['#items']) ? $block_build['#items'] : [];
|
||||
$this->assertIdentical($active_trail_expectations[$id], $this->convertBuiltMenuToIdTree($items), format_string('Menu block %id with an active trail renders the expected tree.', ['%id' => $id]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to allow for easy menu link tree structure assertions.
|
||||
*
|
||||
* Converts the result of MenuLinkTree::build() in a "menu link ID tree".
|
||||
*
|
||||
* @param array $build
|
||||
* The return value of MenuLinkTree::build()
|
||||
*
|
||||
* @return array
|
||||
* The "menu link ID tree" representation of the given render array.
|
||||
*/
|
||||
protected function convertBuiltMenuToIdTree(array $build) {
|
||||
$level = [];
|
||||
foreach (Element::children($build) as $id) {
|
||||
$level[$id] = [];
|
||||
if (isset($build[$id]['below'])) {
|
||||
$level[$id] = $this->convertBuiltMenuToIdTree($build[$id]['below']);
|
||||
}
|
||||
}
|
||||
return $level;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Common;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Test page rendering hooks.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class PageRenderTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests hook_page_attachments() exceptions.
|
||||
*/
|
||||
function testHookPageAttachmentsExceptions() {
|
||||
$this->enableModules(['common_test', 'system']);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
$this->assertPageRenderHookExceptions('common_test', 'hook_page_attachments');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests hook_page_attachments_alter() exceptions.
|
||||
*/
|
||||
function testHookPageAlter() {
|
||||
$this->enableModules(['common_test', 'system']);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
$this->assertPageRenderHookExceptions('common_test', 'hook_page_attachments_alter');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts whether expected exceptions are thrown for invalid hook implementations.
|
||||
*
|
||||
* @param string $module
|
||||
* The module whose invalid logic in its hooks to enable.
|
||||
* @param string $hook
|
||||
* The page render hook to assert expected exceptions for.
|
||||
*/
|
||||
function assertPageRenderHookExceptions($module, $hook) {
|
||||
$html_renderer = \Drupal::getContainer()->get('main_content_renderer.html');
|
||||
|
||||
// Assert a valid hook implementation doesn't trigger an exception.
|
||||
$page = [];
|
||||
$html_renderer->invokePageAttachmentHooks($page);
|
||||
|
||||
// Assert that hooks can set cache tags.
|
||||
$this->assertEqual($page['#cache']['tags'], ['example']);
|
||||
$this->assertEqual($page['#cache']['contexts'], ['user.permissions']);
|
||||
|
||||
// Assert an invalid hook implementation doesn't trigger an exception.
|
||||
\Drupal::state()->set($module . '.' . $hook . '.descendant_attached', TRUE);
|
||||
$assertion = $hook . '() implementation that sets #attached on a descendant triggers an exception';
|
||||
$page = [];
|
||||
try {
|
||||
$html_renderer->invokePageAttachmentHooks($page);
|
||||
$this->error($assertion);
|
||||
}
|
||||
catch (\LogicException $e) {
|
||||
$this->pass($assertion);
|
||||
$this->assertEqual($e->getMessage(), 'Only #attached and #cache may be set in ' . $hook . '().');
|
||||
}
|
||||
\Drupal::state()->set('bc_test.' . $hook . '.descendant_attached', FALSE);
|
||||
|
||||
// Assert an invalid hook implementation doesn't trigger an exception.
|
||||
\Drupal::state()->set('bc_test.' . $hook . '.render_array', TRUE);
|
||||
$assertion = $hook . '() implementation that sets a child render array triggers an exception';
|
||||
$page = [];
|
||||
try {
|
||||
$html_renderer->invokePageAttachmentHooks($page);
|
||||
$this->error($assertion);
|
||||
}
|
||||
catch (\LogicException $e) {
|
||||
$this->pass($assertion);
|
||||
$this->assertEqual($e->getMessage(), 'Only #attached and #cache may be set in ' . $hook . '().');
|
||||
}
|
||||
\Drupal::state()->set($module . '.' . $hook . '.render_array', FALSE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Common;
|
||||
|
||||
use Drupal\Core\Extension\ExtensionDiscovery;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests scanning system directories in drupal_system_listing().
|
||||
*
|
||||
* @group Common
|
||||
*/
|
||||
class SystemListingTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests that files in different directories take precedence as expected.
|
||||
*/
|
||||
function testDirectoryPrecedence() {
|
||||
// Define the module files we will search for, and the directory precedence
|
||||
// we expect.
|
||||
$expected_directories = array(
|
||||
// When both copies of the module are compatible with Drupal core, the
|
||||
// copy in the profile directory takes precedence.
|
||||
'drupal_system_listing_compatible_test' => array(
|
||||
'core/profiles/testing/modules',
|
||||
'core/modules/system/tests/modules',
|
||||
),
|
||||
);
|
||||
|
||||
// This test relies on two versions of the same module existing in
|
||||
// different places in the filesystem. Without that, the test has no
|
||||
// meaning, so assert their presence first.
|
||||
foreach ($expected_directories as $module => $directories) {
|
||||
foreach ($directories as $directory) {
|
||||
$filename = "$directory/$module/$module.info.yml";
|
||||
$this->assertTrue(file_exists(\Drupal::root() . '/' . $filename), format_string('@filename exists.', array('@filename' => $filename)));
|
||||
}
|
||||
}
|
||||
|
||||
// Now scan the directories and check that the files take precedence as
|
||||
// expected.
|
||||
$listing = new ExtensionDiscovery(\Drupal::root());
|
||||
$listing->setProfileDirectories(array('core/profiles/testing'));
|
||||
$files = $listing->scan('module');
|
||||
foreach ($expected_directories as $module => $directories) {
|
||||
$expected_directory = array_shift($directories);
|
||||
$expected_uri = "$expected_directory/$module/$module.info.yml";
|
||||
$this->assertEqual($files[$module]->getPathname(), $expected_uri, format_string('Module @actual was found at @expected.', array(
|
||||
'@actual' => $files[$module]->getPathname(),
|
||||
'@expected' => $expected_uri,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that directories matching file_scan_ignore_directories are ignored
|
||||
*/
|
||||
public function testFileScanIgnoreDirectory() {
|
||||
$listing = new ExtensionDiscovery(\Drupal::root(), FALSE);
|
||||
$listing->setProfileDirectories(array('core/profiles/testing'));
|
||||
$files = $listing->scan('module');
|
||||
$this->assertArrayHasKey('drupal_system_listing_compatible_test', $files);
|
||||
|
||||
// Reset the static to force a rescan of the directories.
|
||||
$reflected_class = new \ReflectionClass(ExtensionDiscovery::class);
|
||||
$reflected_property = $reflected_class->getProperty('files');
|
||||
$reflected_property->setAccessible(TRUE);
|
||||
$reflected_property->setValue($reflected_class, []);
|
||||
|
||||
$this->setSetting('file_scan_ignore_directories', ['drupal_system_listing_compatible_test']);
|
||||
$listing = new ExtensionDiscovery(\Drupal::root(), FALSE);
|
||||
$listing->setProfileDirectories(array('core/profiles/testing'));
|
||||
$files = $listing->scan('module');
|
||||
$this->assertArrayNotHasKey('drupal_system_listing_compatible_test', $files);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
namespace Drupal\Tests\system\Kernel\Extension;
|
||||
|
||||
use Drupal\Core\Extension\MissingDependencyException;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use \Drupal\Core\Extension\ModuleUninstallValidatorException;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
@ -36,16 +35,6 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
system_rebuild_module_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
parent::register($container);
|
||||
// Put a fake route bumper on the container to be called during uninstall.
|
||||
$container
|
||||
->register('router.dumper', 'Drupal\Core\Routing\NullMatcherDumper');
|
||||
}
|
||||
|
||||
/**
|
||||
* The basic functionality of retrieving enabled modules.
|
||||
*/
|
||||
|
|
|
@ -16,7 +16,7 @@ class MigrateSystemImageGdTest extends MigrateDrupal6TestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_image_gd');
|
||||
$this->executeMigration('system_image_gd');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@ class MigrateSystemImageTest extends MigrateDrupal6TestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_image');
|
||||
$this->executeMigration('system_image');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,7 +19,7 @@ class MigrateSystemLoggingTest extends MigrateDrupal6TestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_logging');
|
||||
$this->executeMigration('system_logging');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@ class MigrateSystemMaintenanceTest extends MigrateDrupal6TestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_maintenance');
|
||||
$this->executeMigration('system_maintenance');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@ class MigrateSystemRssTest extends MigrateDrupal6TestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_rss');
|
||||
$this->executeMigration('system_rss');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@ class MigrateSystemSiteTest extends MigrateDrupal6TestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_site');
|
||||
$this->executeMigration('system_site');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Migrates various configuration objects owned by the System module.
|
||||
*
|
||||
* @group migrate_drupal_7
|
||||
*/
|
||||
class MigrateSystemConfigurationTest extends MigrateDrupal7TestBase {
|
||||
|
||||
public static $modules = ['action', 'file', 'system'];
|
||||
|
||||
protected $expectedConfig = [
|
||||
'system.authorize' => [
|
||||
'filetransfer_default' => 'ftp',
|
||||
],
|
||||
'system.cron' => [
|
||||
'threshold' => [
|
||||
// autorun is not handled by the migration.
|
||||
// 'autorun' => 0,
|
||||
'requirements_warning' => 172800,
|
||||
'requirements_error' => 1209600,
|
||||
],
|
||||
],
|
||||
'system.date' => [
|
||||
'country' => [
|
||||
'default' => 'US',
|
||||
],
|
||||
'first_day' => 1,
|
||||
'timezone' => [
|
||||
'default' => 'America/Chicago',
|
||||
'user' => [
|
||||
'configurable' => TRUE,
|
||||
'warn' => TRUE,
|
||||
// DRUPAL_USER_TIMEZONE_SELECT (D7 API)
|
||||
'default' => 2,
|
||||
],
|
||||
],
|
||||
],
|
||||
'system.file' => [
|
||||
'allow_insecure_uploads' => TRUE,
|
||||
// default_scheme is not handled by the migration.
|
||||
'default_scheme' => 'public',
|
||||
'path' => [
|
||||
'temporary' => '/tmp',
|
||||
],
|
||||
// temporary_maximum_age is not handled by the migration.
|
||||
'temporary_maximum_age' => 21600,
|
||||
],
|
||||
'system.image.gd' => [
|
||||
'jpeg_quality' => 80,
|
||||
],
|
||||
'system.image' => [
|
||||
'toolkit' => 'gd',
|
||||
],
|
||||
'system.logging' => [
|
||||
'error_level' => 'some',
|
||||
],
|
||||
'system.mail' => [
|
||||
'interface' => [
|
||||
'default' => 'php_mail',
|
||||
],
|
||||
],
|
||||
'system.maintenance' => [
|
||||
'message' => 'This is a custom maintenance mode message.',
|
||||
// langcode is not handled by the migration.
|
||||
'langcode' => 'en',
|
||||
],
|
||||
'system.performance' => [
|
||||
'cache' => [
|
||||
'page' => [
|
||||
'max_age' => 300,
|
||||
],
|
||||
],
|
||||
'css' => [
|
||||
'preprocess' => TRUE,
|
||||
// gzip is not handled by the migration.
|
||||
'gzip' => TRUE,
|
||||
],
|
||||
// fast_404 is not handled by the migration.
|
||||
'fast_404' => [
|
||||
'enabled' => TRUE,
|
||||
'paths' => '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i',
|
||||
'exclude_paths' => '/\/(?:styles|imagecache)\//',
|
||||
'html' => '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>',
|
||||
],
|
||||
'js' => [
|
||||
'preprocess' => FALSE,
|
||||
// gzip is not handled by the migration.
|
||||
'gzip' => TRUE,
|
||||
],
|
||||
// stale_file_threshold is not handled by the migration.
|
||||
'stale_file_threshold' => 2592000,
|
||||
'response' => [
|
||||
'gzip' => TRUE,
|
||||
],
|
||||
],
|
||||
'system.rss' => [
|
||||
'channel' => [
|
||||
'description' => '',
|
||||
],
|
||||
'items' => [
|
||||
'limit' => 27,
|
||||
'view_mode' => 'fulltext',
|
||||
],
|
||||
'langcode' => 'en',
|
||||
],
|
||||
'system.site' => [
|
||||
// uuid is not handled by the migration.
|
||||
'uuid' => '',
|
||||
'name' => 'The Site Name',
|
||||
'mail' => 'joseph@flattandsons.com',
|
||||
'slogan' => 'The Slogan',
|
||||
'page' => [
|
||||
'403' => '/node',
|
||||
'404' => '/node',
|
||||
'front' => '/node',
|
||||
],
|
||||
'admin_compact_mode' => TRUE,
|
||||
'weight_select_max' => 40,
|
||||
// langcode and default_langcode are not handled by the migration.
|
||||
'langcode' => 'en',
|
||||
'default_langcode' => 'en',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$migrations = [
|
||||
'd7_system_authorize',
|
||||
'd7_system_cron',
|
||||
'd7_system_date',
|
||||
'd7_system_file',
|
||||
'system_image_gd',
|
||||
'system_image',
|
||||
'system_logging',
|
||||
'd7_system_mail',
|
||||
'system_maintenance',
|
||||
'd7_system_performance',
|
||||
'system_rss',
|
||||
'system_site',
|
||||
];
|
||||
$this->executeMigrations($migrations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that all expected configuration gets migrated.
|
||||
*/
|
||||
public function testConfigurationMigration() {
|
||||
foreach ($this->expectedConfig as $config_id => $values) {
|
||||
if ($config_id == 'system.mail') {
|
||||
$actual = \Drupal::config($config_id)->getRawData();
|
||||
}
|
||||
else {
|
||||
$actual = \Drupal::config($config_id)->get();
|
||||
}
|
||||
unset($actual['_core']);
|
||||
$this->assertSame($actual, $values, $config_id . ' matches expected values.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -99,10 +99,10 @@ class DbCommandBaseTest extends KernelTestBase {
|
|||
$this->assertEquals('extra2', $command->getDatabaseConnection($command_tester->getInput())->tablePrefix());
|
||||
|
||||
// This breaks simpletest cleanup.
|
||||
// $command_tester->execute([
|
||||
// '--prefix' => 'notsimpletest',
|
||||
// ]);
|
||||
// $this->assertEquals('notsimpletest', $command->getDatabaseConnection($command_tester->getInput())->tablePrefix());
|
||||
// $command_tester->execute([
|
||||
// '--prefix' => 'notsimpletest',
|
||||
// ]);
|
||||
// $this->assertEquals('notsimpletest', $command->getDatabaseConnection($command_tester->getInput())->tablePrefix());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\System;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the effectiveness of hook_system_info_alter().
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class InfoAlterTest extends KernelTestBase {
|
||||
|
||||
public static $modules = array('system');
|
||||
|
||||
/**
|
||||
* Tests that theme .info.yml data is rebuild after enabling a module.
|
||||
*
|
||||
* Tests that info data is rebuilt after a module that implements
|
||||
* hook_system_info_alter() is enabled. Also tests if core *_list() functions
|
||||
* return freshly altered info.
|
||||
*/
|
||||
function testSystemInfoAlter() {
|
||||
\Drupal::state()->set('module_required_test.hook_system_info_alter', TRUE);
|
||||
$info = system_rebuild_module_data();
|
||||
$this->assertFalse(isset($info['node']->info['required']), 'Before the module_required_test is installed the node module is not required.');
|
||||
|
||||
// Enable the test module.
|
||||
\Drupal::service('module_installer')->install(array('module_required_test'), FALSE);
|
||||
$this->assertTrue(\Drupal::moduleHandler()->moduleExists('module_required_test'), 'Test required module is enabled.');
|
||||
|
||||
$info = system_rebuild_module_data();
|
||||
$this->assertTrue($info['node']->info['required'], 'After the module_required_test is installed the node module is required.');
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
# Themes are not supposed to provide/install this kind of config normally.
|
||||
# This exists for testing purposes only.
|
||||
# @see \Drupal\system\Tests\Extension\ThemeInstallerTest
|
||||
# @see \Drupal\KernelTests\Core\Theme\ThemeInstallerTest
|
||||
id: fancy
|
||||
label: 'Fancy date'
|
||||
status: true
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
name: 'Test theme libraries empty'
|
||||
type: theme
|
||||
description: 'Test theme with empty libraries in theme.info.yml'
|
||||
version: VERSION
|
||||
base theme: classy
|
||||
core: 8.x
|
||||
libraries:
|
||||
|
Reference in a new issue