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:
Pantheon Automation 2016-10-06 15:16:20 -07:00 committed by Greg Anderson
parent 2f563ab520
commit f1c8716f57
1732 changed files with 52334 additions and 11780 deletions

View 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();

View 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();
}

View file

@ -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();

View file

@ -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();

View file

@ -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();

View file

@ -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();

View file

@ -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();
}

View file

@ -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();

View file

@ -0,0 +1 @@
bogus_key: 'Should be cleaned by system_update_8200'

View 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'

View file

@ -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'

View file

@ -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,
]),
],
],
),
);

View file

@ -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;
}
}

View file

@ -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());
}
}

View file

@ -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());
}
}

View file

@ -0,0 +1,6 @@
name: CSRF test
type: module
description: 'Support testing protecting routes with CSRF token.'
package: Testing
version: VERSION
core: 8.x

View file

@ -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'

View file

@ -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']);
}
}

View file

@ -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!');
}
}

View file

@ -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;
}

View file

@ -88,7 +88,7 @@ display:
entity_field: title
filters:
status:
value: true
value: '1'
table: node_field_data
field: status
id: status

View file

@ -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);
}
/**

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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'

View file

@ -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',

View file

@ -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',

View file

@ -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);
}
}

View file

@ -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

View file

@ -0,0 +1,5 @@
services:
module_install_class_loader_test1.event_subscriber:
class: Drupal\module_install_class_loader_test1\EventSubscriber
tags:
- { name: event_subscriber }

View file

@ -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;
}
}

View file

@ -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

View file

@ -0,0 +1,5 @@
services:
module_install_class_loader_test1.event_subscriber:
class: Drupal\module_install_class_loader_test2\EventSubscriber
tags:
- { name: event_subscriber }

View file

@ -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 [];
}
}

View file

@ -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

View file

@ -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 { }

View file

@ -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;
}
}

View file

@ -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'

View file

@ -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>'];
}
}

View file

@ -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();.,\\\/-_{}',

View file

@ -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'

View file

@ -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());
}
}
}
}

View 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());
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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.
*/

View file

@ -16,7 +16,7 @@ class MigrateSystemImageGdTest extends MigrateDrupal6TestBase {
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_system_image_gd');
$this->executeMigration('system_image_gd');
}
/**

View file

@ -16,7 +16,7 @@ class MigrateSystemImageTest extends MigrateDrupal6TestBase {
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_system_image');
$this->executeMigration('system_image');
}
/**

View file

@ -19,7 +19,7 @@ class MigrateSystemLoggingTest extends MigrateDrupal6TestBase {
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_system_logging');
$this->executeMigration('system_logging');
}
/**

View file

@ -16,7 +16,7 @@ class MigrateSystemMaintenanceTest extends MigrateDrupal6TestBase {
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_system_maintenance');
$this->executeMigration('system_maintenance');
}
/**

View file

@ -16,7 +16,7 @@ class MigrateSystemRssTest extends MigrateDrupal6TestBase {
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_system_rss');
$this->executeMigration('system_rss');
}
/**

View file

@ -16,7 +16,7 @@ class MigrateSystemSiteTest extends MigrateDrupal6TestBase {
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_system_site');
$this->executeMigration('system_site');
}
/**

View file

@ -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.');
}
}
}

View file

@ -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());
}
}

View file

@ -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.');
}
}

View file

@ -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

View file

@ -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: