Update to Drupal 8.0.0-beta15. For more information, see: https://www.drupal.org/node/2563023
This commit is contained in:
parent
2720a9ec4b
commit
f3791f1da3
1898 changed files with 54300 additions and 11481 deletions
20
core/modules/system/tests/fixtures/update/block.block.testfor507488.yml
vendored
Normal file
20
core/modules/system/tests/fixtures/update/block.block.testfor507488.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
uuid: ee7c230c-337b-4e8f-8600-d65bfd34f171
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
theme:
|
||||
- seven
|
||||
id: seven_local_actions
|
||||
theme: seven
|
||||
region: content
|
||||
weight: -10
|
||||
provider: null
|
||||
plugin: local_actions_block
|
||||
settings:
|
||||
id: local_actions_block
|
||||
label: 'Primary admin actions'
|
||||
label_display: '0'
|
||||
cache:
|
||||
max_age: 0
|
||||
status: true
|
||||
visibility: { }
|
|
@ -27,4 +27,4 @@ visibility:
|
|||
page: page
|
||||
negate: false
|
||||
context_mapping:
|
||||
baloney: baloney.spam
|
||||
baloney: baloney_spam
|
||||
|
|
Binary file not shown.
49
core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php
vendored
Normal file
49
core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Partial database to mimic the installation of the block_test module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Set the schema version.
|
||||
$connection->insert('key_value')
|
||||
->fields([
|
||||
'collection' => 'system.schema',
|
||||
'name' => 'block_test',
|
||||
'value' => 'i:8000;',
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Update core.extension.
|
||||
$extensions = $connection->select('config')
|
||||
->fields('config', ['data'])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$extensions = unserialize($extensions);
|
||||
$extensions['module']['block_test'] = 8000;
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize($extensions),
|
||||
])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
||||
|
||||
// Install the block configuration.
|
||||
$config = file_get_contents(__DIR__ . '/../../../../block/tests/modules/block_test/config/install/block.block.test_block.yml');
|
||||
$config = Yaml::parse($config);
|
||||
$connection->insert('config')
|
||||
->fields(['data', 'name', 'collection'])
|
||||
->values([
|
||||
'name' => 'block.block.test_block',
|
||||
'data' => serialize($config),
|
||||
'collection' => '',
|
||||
])
|
||||
->execute();
|
18
core/modules/system/tests/fixtures/update/drupal-8.broken_routing.php
vendored
Normal file
18
core/modules/system/tests/fixtures/update/drupal-8.broken_routing.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
$config = unserialize($connection->query("SELECT data FROM {config} where name = :name", [':name' => 'core.extension'])->fetchField());
|
||||
$config['module']['update_script_test'] = 0;
|
||||
$connection->update('config')
|
||||
->fields(['data' => serialize($config)])
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
||||
|
||||
$connection->insert('key_value')
|
||||
->fields(['collection' => 'system.schema', 'name' => 'update_script_test', 'value' => serialize(8000)])
|
||||
->execute();
|
||||
|
BIN
core/modules/system/tests/fixtures/update/drupal-8.filled.standard.php.gz
vendored
Normal file
BIN
core/modules/system/tests/fixtures/update/drupal-8.filled.standard.php.gz
vendored
Normal file
Binary file not shown.
BIN
core/modules/system/tests/fixtures/update/drupal-8.language-enabled.php
vendored
Normal file
BIN
core/modules/system/tests/fixtures/update/drupal-8.language-enabled.php
vendored
Normal file
Binary file not shown.
60
core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php
vendored
Normal file
60
core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains database additions to drupal-8.bare.standard.php.gz for testing the
|
||||
* upgrade path of https://www.drupal.org/node/507488.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Structure of a custom block with visibility settings.
|
||||
$block_configs[] = \Drupal\Component\Serialization\Yaml::decode(file_get_contents(__DIR__ . '/block.block.testfor507488.yml'));
|
||||
|
||||
foreach ($block_configs as $block_config) {
|
||||
$connection->insert('config')
|
||||
->fields([
|
||||
'collection',
|
||||
'name',
|
||||
'data',
|
||||
])
|
||||
->values([
|
||||
'collection' => '',
|
||||
'name' => 'block.block.' . $block_config['id'],
|
||||
'data' => serialize($block_config),
|
||||
])
|
||||
->execute();
|
||||
}
|
||||
|
||||
// Update the config entity query "index".
|
||||
$existing_blocks = $connection->select('key_value')
|
||||
->fields('key_value', ['value'])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:seven')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$existing_blocks = unserialize($existing_blocks);
|
||||
|
||||
$connection->update('key_value')
|
||||
->fields([
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.seven_local_actions']))
|
||||
])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:seven')
|
||||
->execute();
|
||||
|
||||
// Enable test theme.
|
||||
$extensions = $connection->select('config')
|
||||
->fields('config', ['data'])
|
||||
->condition('name', 'core.extension')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$extensions = unserialize($extensions);
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_theme' => 0]]))
|
||||
])
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
54
core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php
vendored
Normal file
54
core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Partial database to mimic the installation of the update_test_schema module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Create the table.
|
||||
$connection->schema()->createTable('update_test_schema_table', array(
|
||||
'fields' => array(
|
||||
'a' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'normal',
|
||||
),
|
||||
'b' => array(
|
||||
'type' => 'blob',
|
||||
'not null' => FALSE,
|
||||
'size' => 'normal',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Set the schema version.
|
||||
$connection->merge('key_value')
|
||||
->condition('collection', 'system.schema')
|
||||
->condition('name', 'update_test_schema')
|
||||
->fields([
|
||||
'collection' => 'system.schema',
|
||||
'name' => 'update_test_schema',
|
||||
'value' => 'i:8000;',
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Update core.extension.
|
||||
$extensions = $connection->select('config')
|
||||
->fields('config', ['data'])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$extensions = unserialize($extensions);
|
||||
$extensions['module']['update_test_schema'] = 8000;
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize($extensions),
|
||||
])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
31
core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php
vendored
Normal file
31
core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains database additions to drupal-8.bare.standard.php.gz for testing the
|
||||
* upgrade path of https://www.drupal.org/node/2455125.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Structure of a view with timestamp fields.
|
||||
$views_configs = [];
|
||||
|
||||
$views_configs[] = \Drupal\Component\Serialization\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(
|
||||
'collection',
|
||||
'name',
|
||||
'data',
|
||||
))
|
||||
->values(array(
|
||||
'collection' => '',
|
||||
'name' => 'views.view.' . $views_config['id'],
|
||||
'data' => serialize($views_config),
|
||||
))
|
||||
->execute();
|
||||
}
|
294
core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.yml
vendored
Normal file
294
core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.yml
vendored
Normal file
|
@ -0,0 +1,294 @@
|
|||
uuid: e693b165-0e14-4dee-9909-9f0892037c23
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- user
|
||||
id: update_test
|
||||
label: 'Update Test'
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: users_field_data
|
||||
base_field: uid
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: perm
|
||||
options:
|
||||
perm: 'access user profiles'
|
||||
cache:
|
||||
type: tag
|
||||
options: { }
|
||||
query:
|
||||
type: views_query
|
||||
options:
|
||||
disable_sql_rewrite: false
|
||||
distinct: false
|
||||
replica: false
|
||||
query_comment: ''
|
||||
query_tags: { }
|
||||
exposed_form:
|
||||
type: basic
|
||||
options:
|
||||
submit_button: Apply
|
||||
reset_button: false
|
||||
reset_button_label: Reset
|
||||
exposed_sorts_label: 'Sort by'
|
||||
expose_sort_order: true
|
||||
sort_asc_label: Asc
|
||||
sort_desc_label: Desc
|
||||
pager:
|
||||
type: none
|
||||
options:
|
||||
items_per_page: 0
|
||||
offset: 0
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: fields
|
||||
fields:
|
||||
name:
|
||||
id: name
|
||||
table: users_field_data
|
||||
field: name
|
||||
entity_type: user
|
||||
entity_field: name
|
||||
label: ''
|
||||
alter:
|
||||
alter_text: false
|
||||
make_link: false
|
||||
absolute: false
|
||||
trim: false
|
||||
word_boundary: false
|
||||
ellipsis: false
|
||||
strip_tags: false
|
||||
html: false
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
plugin_id: field
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
exclude: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: true
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_alter_empty: true
|
||||
click_sort_column: value
|
||||
type: user_name
|
||||
settings: { }
|
||||
group_column: value
|
||||
group_columns: { }
|
||||
group_rows: true
|
||||
delta_limit: 0
|
||||
delta_offset: 0
|
||||
delta_reversed: false
|
||||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: false
|
||||
created:
|
||||
id: created
|
||||
table: users_field_data
|
||||
field: created
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
date_format: long
|
||||
custom_date_format: ''
|
||||
timezone: Africa/Abidjan
|
||||
entity_type: user
|
||||
entity_field: created
|
||||
plugin_id: date
|
||||
created_1:
|
||||
id: created_1
|
||||
table: users_field_data
|
||||
field: created
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
date_format: 'raw time ago'
|
||||
custom_date_format: ''
|
||||
timezone: ''
|
||||
entity_type: user
|
||||
entity_field: created
|
||||
plugin_id: date
|
||||
created_2:
|
||||
id: created_2
|
||||
table: users_field_data
|
||||
field: created
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
date_format: 'time ago'
|
||||
custom_date_format: ''
|
||||
timezone: ''
|
||||
entity_type: user
|
||||
entity_field: created
|
||||
plugin_id: date
|
||||
filters: { }
|
||||
sorts: { }
|
||||
title: 'Update Test'
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships: { }
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- user.permissions
|
||||
cacheable: false
|
||||
block_1:
|
||||
display_plugin: block
|
||||
id: block_1
|
||||
display_title: Block
|
||||
position: 1
|
||||
display_options:
|
||||
display_extenders: { }
|
||||
allow:
|
||||
items_per_page: false
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- user.permissions
|
||||
cacheable: false
|
|
@ -5,7 +5,9 @@
|
|||
* Batch callbacks for the Batch API tests.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
||||
/**
|
||||
* Implements callback_batch_operation().
|
||||
|
@ -86,10 +88,9 @@ function _batch_test_nested_batch_callback() {
|
|||
* Provides a common 'finished' callback for batches 1 to 4.
|
||||
*/
|
||||
function _batch_test_finished_helper($batch_id, $success, $results, $operations) {
|
||||
$messages = array("results for batch $batch_id");
|
||||
if ($results) {
|
||||
foreach ($results as $op => $op_results) {
|
||||
$messages[] = 'op '. SafeMarkup::escape($op) . ': processed ' . count($op_results) . ' elements';
|
||||
$messages[] = 'op '. Html::escape($op) . ': processed ' . count($op_results) . ' elements';
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -102,7 +103,20 @@ function _batch_test_finished_helper($batch_id, $success, $results, $operations)
|
|||
$messages[] = t('An error occurred while processing @op with arguments:<br />@args', array('@op' => $error_operation[0], '@args' => print_r($error_operation[1], TRUE)));
|
||||
}
|
||||
|
||||
drupal_set_message(SafeMarkup::set(implode('<br>', $messages)));
|
||||
// Use item list template to render the messages.
|
||||
$error_message = [
|
||||
'#type' => 'inline_template',
|
||||
'#template' => 'results for batch {{ batch_id }}{{ errors }}',
|
||||
'#context' => [
|
||||
'batch_id' => $batch_id,
|
||||
'errors' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $messages,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
drupal_set_message(\Drupal::service('renderer')->renderPlain($error_message));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,6 +137,16 @@ function _batch_test_finished_1($success, $results, $operations) {
|
|||
_batch_test_finished_helper(1, $success, $results, $operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements callback_batch_finished().
|
||||
*
|
||||
* Triggers 'finished' callback for batch 1.
|
||||
*/
|
||||
function _batch_test_finished_1_finished($success, $results, $operations) {
|
||||
_batch_test_finished_helper(1, $success, $results, $operations);
|
||||
return new RedirectResponse(Url::fromRoute('test_page_test.test_page', [], ['absolute' => TRUE])->toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements callback_batch_finished().
|
||||
*
|
||||
|
|
|
@ -31,6 +31,14 @@ batch_test.no_form:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
batch_test.finish_redirect:
|
||||
path: '/batch-test/finish-redirect'
|
||||
defaults:
|
||||
_controller: '\Drupal\batch_test\Controller\BatchTestController::testFinishRedirect'
|
||||
_title: 'Simple page with finish redirect call'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
batch_test.test_form:
|
||||
path: '/batch-test'
|
||||
defaults:
|
||||
|
|
|
@ -72,6 +72,21 @@ class BatchTestController {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a batch process without a form submission and a finish redirect.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|null
|
||||
* A redirect response if the batch is progressive. No return value otherwise.
|
||||
*/
|
||||
public function testFinishRedirect() {
|
||||
batch_test_stack(NULL, TRUE);
|
||||
|
||||
$batch = _batch_test_batch_1();
|
||||
$batch['finished'] = '_batch_test_finished_1_finished';
|
||||
batch_set($batch);
|
||||
return batch_process('batch-test/redirect');
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits the 'Chained' form programmatically.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
common_test.l_active_class:
|
||||
path: '/common-test/type-link-active-class'
|
||||
defaults:
|
||||
_title: 'Test active link class'
|
||||
_controller: '\Drupal\common_test\Controller\CommonTestController::typeLinkActiveClass'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
services:
|
||||
main_content_renderer.json:
|
||||
class: Drupal\common_test\Render\MainContent\JsonRenderer
|
||||
arguments: ['@title_resolver', '@renderer']
|
||||
tags:
|
||||
- { name: render.main_content_renderer, format: json }
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\common_test\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
|
@ -89,7 +89,7 @@ class CommonTestController {
|
|||
*/
|
||||
public function destination() {
|
||||
$destination = \Drupal::destination()->getAsArray();
|
||||
$output = "The destination: " . SafeMarkup::checkPlain($destination['destination']);
|
||||
$output = "The destination: " . Html::escape($destination['destination']);
|
||||
return new Response($output);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\common_test\Render\MainContent\JsonRenderer.
|
||||
*/
|
||||
|
||||
namespace Drupal\common_test\Render\MainContent;
|
||||
|
||||
use Drupal\Core\Cache\CacheableJsonResponse;
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Controller\TitleResolverInterface;
|
||||
use Drupal\Core\Render\MainContent\MainContentRendererInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Default main content renderer for JSON requests.
|
||||
*/
|
||||
class JsonRenderer implements MainContentRendererInterface {
|
||||
|
||||
/**
|
||||
* The title resolver.
|
||||
*
|
||||
* @var \Drupal\Core\Controller\TitleResolverInterface
|
||||
*/
|
||||
protected $titleResolver;
|
||||
|
||||
/**
|
||||
* The renderer service.
|
||||
*
|
||||
* @var \Drupal\Core\Render\RendererInterface
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* Constructs a new JsonRenderer.
|
||||
*
|
||||
* @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
|
||||
* The title resolver.
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
* The renderer service.
|
||||
*/
|
||||
public function __construct(TitleResolverInterface $title_resolver, RendererInterface $renderer) {
|
||||
$this->titleResolver = $title_resolver;
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) {
|
||||
$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());
|
||||
}
|
||||
|
||||
$response = new CacheableJsonResponse($json, 200);
|
||||
$response->addCacheableDependency(CacheableMetadata::createFromRenderArray($main_content));
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\database_test\Form;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\user\Entity\User;
|
||||
|
@ -56,8 +55,8 @@ class DatabaseTestForm extends FormBase {
|
|||
|
||||
foreach (User::loadMultiple($uids) as $account) {
|
||||
$options[$account->id()] = array(
|
||||
'title' => array('data' => array('#title' => SafeMarkup::checkPlain($account->getUsername()))),
|
||||
'username' => SafeMarkup::checkPlain($account->getUsername()),
|
||||
'title' => array('data' => array('#title' => $account->getUsername())),
|
||||
'username' => $account->getUsername(),
|
||||
'status' => $account->isActive() ? t('active') : t('blocked'),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* Install, update and uninstall functions for the entity_test module.
|
||||
*/
|
||||
|
||||
use Drupal\system\Tests\Update\DbUpdatesTrait;
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
|
@ -49,3 +51,6 @@ function entity_test_schema() {
|
|||
);
|
||||
return $schema;
|
||||
}
|
||||
|
||||
DbUpdatesTrait::includeUpdates('entity_test', 'entity_definition_updates');
|
||||
DbUpdatesTrait::includeUpdates('entity_test', 'status_report');
|
||||
|
|
|
@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityTypeInterface;
|
|||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
|
@ -119,14 +120,25 @@ function entity_test_entity_base_field_info(EntityTypeInterface $entity_type) {
|
|||
* Implements hook_entity_base_field_info_alter().
|
||||
*/
|
||||
function entity_test_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
|
||||
if ($entity_type->id() == 'entity_test_mulrev' && ($names = \Drupal::state()->get('entity_test.field_definitions.translatable'))) {
|
||||
$state = \Drupal::state();
|
||||
if ($entity_type->id() == 'entity_test_mulrev' && ($names = $state->get('entity_test.field_definitions.translatable'))) {
|
||||
foreach ($names as $name => $value) {
|
||||
$fields[$name]->setTranslatable($value);
|
||||
}
|
||||
}
|
||||
if ($entity_type->id() == 'node' && Drupal::state()->get('entity_test.node_remove_status_field')) {
|
||||
if ($entity_type->id() == 'node' && $state->get('entity_test.node_remove_status_field')) {
|
||||
unset($fields['status']);
|
||||
}
|
||||
if ($entity_type->id() == 'entity_test' && $state->get('entity_test.remove_name_field')) {
|
||||
unset($fields['name']);
|
||||
}
|
||||
// In 8001 we are assuming that a new definition with multiple cardinality has
|
||||
// been deployed.
|
||||
// @todo Remove this if we end up using state definitions at runtime. See
|
||||
// https://www.drupal.org/node/2554235.
|
||||
if ($entity_type->id() == 'entity_test' && $state->get('entity_test.db_updates.entity_definition_updates') == 8001) {
|
||||
$fields['user_id']->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -600,7 +612,7 @@ function entity_test_field_default_value(FieldableEntityInterface $entity, Field
|
|||
* @param string $hook
|
||||
* The hook name.
|
||||
* @param mixed $data
|
||||
* Arbitrary data associated to the hook invocation.
|
||||
* Arbitrary data associated with the hook invocation.
|
||||
*/
|
||||
function _entity_test_record_hooks($hook, $data) {
|
||||
$state = \Drupal::state();
|
||||
|
|
|
@ -4,7 +4,7 @@ entity.entity_test.canonical:
|
|||
_entity_view: 'entity_test.full'
|
||||
_title: 'Test full view mode'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
_entity_access: 'entity_test.view'
|
||||
|
||||
entity.entity_test.render_options:
|
||||
path: '/entity_test_converter/{foo}'
|
||||
|
@ -15,7 +15,7 @@ entity.entity_test.render_options:
|
|||
defaults:
|
||||
_entity_view: 'entity_test.full'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
_entity_access: 'foo.view'
|
||||
|
||||
entity.entity_test.render_no_view_mode:
|
||||
path: '/entity_test_no_view_mode/{entity_test}'
|
||||
|
|
|
@ -23,7 +23,6 @@ use Drupal\Core\Entity\EntityTypeInterface;
|
|||
* },
|
||||
* base_table = "entity_test_update",
|
||||
* revision_table = "entity_test_update_revision",
|
||||
* fieldable = TRUE,
|
||||
* persistent_cache = FALSE,
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
|
|
|
@ -30,7 +30,7 @@ class EntityTestListBuilder extends EntityListBuilder {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildRow(EntityInterface $entity) {
|
||||
$row['label'] = $this->getLabel($entity);
|
||||
$row['label'] = $entity->label();
|
||||
$row['id'] = $entity->id();
|
||||
return $row + parent::buildRow($entity);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\entity_test;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityViewBuilder;
|
||||
|
||||
|
@ -36,7 +35,7 @@ class EntityTestViewBuilder extends EntityViewBuilder {
|
|||
foreach ($entities as $id => $entity) {
|
||||
$build[$id]['label'] = array(
|
||||
'#weight' => -100,
|
||||
'#markup' => SafeMarkup::checkPlain($entity->label()),
|
||||
'#plain_text' => $entity->label(),
|
||||
);
|
||||
$build[$id]['separator'] = array(
|
||||
'#weight' => -150,
|
||||
|
@ -44,7 +43,7 @@ class EntityTestViewBuilder extends EntityViewBuilder {
|
|||
);
|
||||
$build[$id]['view_mode'] = array(
|
||||
'#weight' => -200,
|
||||
'#markup' => SafeMarkup::checkPlain($view_mode),
|
||||
'#plain_text' => $view_mode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\entity_test;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +19,7 @@ class EntityTestViewBuilderOverriddenView extends EntityTestViewBuilder {
|
|||
*/
|
||||
public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
|
||||
$build = [];
|
||||
$build[$entity->id()]['#markup'] = SafeMarkup::checkPlain($entity->label());
|
||||
$build[$entity->id()]['#plain_text'] = $entity->label();
|
||||
return $build;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,8 @@ class EntityTestRoutes {
|
|||
$routes["entity.$entity_type_id.admin_form"] = new Route(
|
||||
"$entity_type_id/structure/{bundle}",
|
||||
array('_controller' => '\Drupal\entity_test\Controller\EntityTestController::testAdmin'),
|
||||
array('_permission' => 'administer entity_test content')
|
||||
array('_permission' => 'administer entity_test content'),
|
||||
array('_admin_route' => TRUE)
|
||||
);
|
||||
}
|
||||
return $routes;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines the 8001 db update for the "entity_definition_updates" group.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
|
||||
/**
|
||||
* Makes the 'user_id' field multiple and migrate its data.
|
||||
*/
|
||||
function entity_test_update_8001() {
|
||||
// To update the field schema we need to have no field data in the storage,
|
||||
// thus we retrieve it, delete it from storage, and write it back to the
|
||||
// storage after updating the schema.
|
||||
$database = \Drupal::database();
|
||||
|
||||
// Retrieve existing field data.
|
||||
$user_ids = $database->select('entity_test', 'et')
|
||||
->fields('et', ['id', 'user_id'])
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
|
||||
// Remove data from the storage.
|
||||
$database->update('entity_test')
|
||||
->fields(['user_id' => NULL])
|
||||
->execute();
|
||||
|
||||
// Update definitions and schema.
|
||||
$manager = \Drupal::entityDefinitionUpdateManager();
|
||||
$storage_definition = $manager->getFieldStorageDefinition('user_id', 'entity_test');
|
||||
$storage_definition->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
$manager->updateFieldStorageDefinition($storage_definition);
|
||||
|
||||
// Restore entity data in the new schema.
|
||||
$insert_query = $database->insert('entity_test__user_id')
|
||||
->fields(['bundle', 'deleted', 'entity_id', 'revision_id', 'langcode', 'delta', 'user_id_target_id']);
|
||||
foreach ($user_ids as $id => $user_id) {
|
||||
$insert_query->values(['entity_test', 0, $id, $id, 'en', 0, $user_id]);
|
||||
}
|
||||
$insert_query->execute();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines the 8002 db update for the "entity_definition_updates" group.
|
||||
*/
|
||||
|
||||
require_once 'entity_definition_updates_8001.inc';
|
||||
|
||||
/**
|
||||
* Makes the 'user_id' field single and migrate its data.
|
||||
*/
|
||||
function entity_test_update_8002() {
|
||||
// To update the field schema we need to have no field data in the storage,
|
||||
// thus we retrieve it, delete it from storage, and write it back to the
|
||||
// storage after updating the schema.
|
||||
$database = \Drupal::database();
|
||||
|
||||
// Retrieve existing entity data.
|
||||
$query = $database->select('entity_test__user_id', 'et')
|
||||
->fields('et', ['entity_id', 'user_id_target_id']);
|
||||
$query->condition('et.delta', 0);
|
||||
$user_ids = $query->execute()->fetchAllKeyed();
|
||||
|
||||
// Remove data from the storage.
|
||||
$database->truncate('entity_test__user_id')->execute();
|
||||
|
||||
// Update definitions and schema.
|
||||
$manager = \Drupal::entityDefinitionUpdateManager();
|
||||
$storage_definition = $manager->getFieldStorageDefinition('user_id', 'entity_test');
|
||||
$storage_definition->setCardinality(1);
|
||||
$manager->updateFieldStorageDefinition($storage_definition);
|
||||
|
||||
// Restore entity data in the new schema.
|
||||
foreach ($user_ids as $id => $user_id) {
|
||||
$database->update('entity_test')
|
||||
->fields(['user_id' => $user_id])
|
||||
->condition('id', $id)
|
||||
->execute();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines the 8001 db update for the "status_report" group.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test update.
|
||||
*/
|
||||
function entity_test_update_8001() {
|
||||
// Empty update, we just want to trigger an error in the status report.
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines the 8002 db update for the "status_report" group.
|
||||
*/
|
||||
|
||||
require_once 'status_report_8001.inc';
|
||||
|
||||
/**
|
||||
* Test update.
|
||||
*/
|
||||
function entity_test_update_8002() {
|
||||
// Empty update, we just want to trigger an update run.
|
||||
}
|
|
@ -6,3 +6,8 @@ services:
|
|||
# Set up a service with a missing class dependency.
|
||||
broken_class_with_missing_dependency:
|
||||
class: Drupal\error_service_test\LonelyMonkeyClass
|
||||
logger.broken:
|
||||
class: Drupal\error_service_test\Logger\TestLog
|
||||
tags:
|
||||
- { name: logger }
|
||||
- { name: backend_overridable }
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\error_service_test\Logger\TestLog.
|
||||
*/
|
||||
|
||||
namespace Drupal\error_service_test\Logger;
|
||||
|
||||
use Drupal\Core\Logger\RfcLoggerTrait;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Throws an exception while logging an exception.
|
||||
*
|
||||
* @see \Drupal\system\Tests\System\UncaughtExceptionTest::testLoggerException()
|
||||
*/
|
||||
class TestLog implements LoggerInterface {
|
||||
use RfcLoggerTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function log($level, $message, array $context = array()) {
|
||||
$trigger = [
|
||||
'%type' => 'Exception',
|
||||
'@message' => 'Deforestation',
|
||||
'%function' => 'Drupal\error_service_test\MonkeysInTheControlRoom->handle()',
|
||||
'severity_level' => 3,
|
||||
'channel' => 'php',
|
||||
];
|
||||
if (array_diff_assoc($trigger, $context) === []) {
|
||||
throw new \Exception('Oh, oh, frustrated monkeys!');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -57,6 +57,10 @@ class MonkeysInTheControlRoom implements HttpKernelInterface {
|
|||
throw new \Exception('Oh oh, bananas in the instruments.');
|
||||
}
|
||||
|
||||
if (\Drupal::state()->get('error_service_test.break_logger')) {
|
||||
throw new \Exception('Deforestation');
|
||||
}
|
||||
|
||||
return $this->app->handle($request, $type, $catch);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,8 +51,8 @@ class ErrorTestController extends ControllerBase {
|
|||
$monkey_love = $bananas;
|
||||
// This will generate a warning.
|
||||
$awesomely_big = 1/0;
|
||||
// This will generate a user error.
|
||||
trigger_error("Drupal is awesome", E_USER_WARNING);
|
||||
// This will generate a user error. Use & to check for double escaping.
|
||||
trigger_error("Drupal & awesome", E_USER_WARNING);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ class ErrorTestController extends ControllerBase {
|
|||
*/
|
||||
public function triggerException() {
|
||||
define('SIMPLETEST_COLLECT_ERRORS', FALSE);
|
||||
throw new \Exception("Drupal is awesome");
|
||||
throw new \Exception("Drupal & awesome");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,3 +93,14 @@ function form_test_user_register_form_rebuild($form, FormStateInterface $form_st
|
|||
drupal_set_message('Form rebuilt.');
|
||||
$form_state->setRebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter() for form_test_vertical_tabs_access_form().
|
||||
*/
|
||||
function form_test_form_form_test_vertical_tabs_access_form_alter(&$form, &$form_state, $form_id) {
|
||||
$form['vertical_tabs1']['#access'] = FALSE;
|
||||
$form['vertical_tabs2']['#access'] = FALSE;
|
||||
$form['tabs3']['#access'] = TRUE;
|
||||
$form['fieldset1']['#access'] = FALSE;
|
||||
$form['container']['#access'] = FALSE;
|
||||
}
|
||||
|
|
|
@ -172,6 +172,14 @@ form_test.storage:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
form_test.vertical_tabs_access:
|
||||
path: '/form_test/vertical-tabs-access'
|
||||
defaults:
|
||||
_form: '\Drupal\form_test\Form\FormTestVerticalTabsAccessForm'
|
||||
_title: 'Vertical tabs tests'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
form_test.state_clean:
|
||||
path: '/form_test/form-state-values-clean'
|
||||
defaults:
|
||||
|
|
|
@ -142,6 +142,15 @@ class FormTestDisabledElementsForm extends FormBase {
|
|||
'#date_timezone' => 'Europe/Berlin',
|
||||
);
|
||||
|
||||
$form['disabled_container']['disabled_container_date'] = array(
|
||||
'#type' => 'date',
|
||||
'#title' => 'date',
|
||||
'#default_value' => '2001-01-13',
|
||||
'#expected_value' => '2001-01-13',
|
||||
'#test_hijack_value' => '2013-01-01',
|
||||
'#date_timezone' => 'Europe/Berlin',
|
||||
);
|
||||
|
||||
|
||||
// Try to hijack the email field with a valid email.
|
||||
$form['disabled_container']['disabled_container_email'] = array(
|
||||
|
|
|
@ -33,7 +33,10 @@ class FormTestRequiredAttributeForm extends FormBase {
|
|||
'#title' => $type,
|
||||
);
|
||||
}
|
||||
|
||||
$form['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => 'Submit',
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\form_test\Form;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
|
@ -139,7 +139,7 @@ class FormTestStorageForm extends FormBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
drupal_set_message("Title: " . SafeMarkup::checkPlain($form_state->getValue('title')));
|
||||
drupal_set_message("Title: " . Html::escape($form_state->getValue('title')));
|
||||
drupal_set_message("Form constructions: " . $_SESSION['constructions']);
|
||||
if ($form_state->has(['thing', 'changed'])) {
|
||||
drupal_set_message("The thing has been changed.");
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\form_test\Form;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
|
@ -57,7 +56,7 @@ class FormTestStoragePageCacheForm extends FormBase {
|
|||
*/
|
||||
function form_test_storage_page_cache_old_build_id($form) {
|
||||
if (isset($form['#build_id_old'])) {
|
||||
$form['test_build_id_old']['#markup'] = SafeMarkup::checkPlain($form['#build_id_old']);
|
||||
$form['test_build_id_old']['#plain_text'] = $form['#build_id_old'];
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\form_test\Form\FormTestVerticalTabsAccessForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\form_test\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
class FormTestVerticalTabsAccessForm extends FormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'form_test_vertical_tabs_access_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form['vertical_tabs1'] = array(
|
||||
'#type' => 'vertical_tabs',
|
||||
);
|
||||
$form['tab1'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Tab 1'),
|
||||
'#collapsible' => TRUE,
|
||||
'#group' => 'vertical_tabs1',
|
||||
);
|
||||
$form['tab1']['field1'] = array(
|
||||
'#title' => t('Field 1'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => TRUE,
|
||||
);
|
||||
$form['tab2'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Tab 2'),
|
||||
'#collapsible' => TRUE,
|
||||
'#group' => 'vertical_tabs1',
|
||||
);
|
||||
$form['tab2']['field2'] = array(
|
||||
'#title' => t('Field 2'),
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => 'field2',
|
||||
);
|
||||
|
||||
$form['fieldset1'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Fieldset'),
|
||||
);
|
||||
$form['fieldset1']['field3'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Field 3'),
|
||||
'#default_value' => TRUE,
|
||||
);
|
||||
|
||||
$form['container'] = array(
|
||||
'#type' => 'container',
|
||||
);
|
||||
$form['container']['field4'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Field 4'),
|
||||
'#default_value' => TRUE,
|
||||
);
|
||||
$form['container']['subcontainer'] = array(
|
||||
'#type' => 'container',
|
||||
);
|
||||
$form['container']['subcontainer']['field5'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Field 5'),
|
||||
'#default_value' => TRUE,
|
||||
);
|
||||
|
||||
$form['vertical_tabs2'] = array(
|
||||
'#type' => 'vertical_tabs',
|
||||
);
|
||||
$form['tab3'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Tab 3'),
|
||||
'#collapsible' => TRUE,
|
||||
'#group' => 'vertical_tabs2',
|
||||
);
|
||||
$form['tab3']['field6'] = array(
|
||||
'#title' => t('Field 6'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => TRUE,
|
||||
);
|
||||
|
||||
$form['actions'] = array(
|
||||
'#type' => 'actions',
|
||||
);
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Submit'),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
$values = $form_state->getValues();
|
||||
if (empty($values['field1'])) {
|
||||
$form_state->setErrorByName('tab1][field1', t('This checkbox inside a vertical tab does not have its default value.'));
|
||||
}
|
||||
if ($values['field2'] != 'field2') {
|
||||
$form_state->setErrorByName('tab2][field2', t('This textfield inside a vertical tab does not have its default value.'));
|
||||
}
|
||||
if (empty($values['field3'])) {
|
||||
$form_state->setErrorByName('fieldset][field3', t('This checkbox inside a fieldset does not have its default value.'));
|
||||
}
|
||||
if (empty($values['field4'])) {
|
||||
$form_state->setErrorByName('container][field4', t('This checkbox inside a container does not have its default value.'));
|
||||
}
|
||||
if (empty($values['field5'])) {
|
||||
$form_state->setErrorByName('container][subcontainer][field5', t('This checkbox inside a nested container does not have its default value.'));
|
||||
}
|
||||
if (empty($values['field5'])) {
|
||||
$form_state->setErrorByName('tab3][field6', t('This checkbox inside a vertical tab whose fieldset access is allowed does not have its default value.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
drupal_set_message(t('The form submitted correctly.'));
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\form_test;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Form\ConfigFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
|
@ -38,7 +37,7 @@ class FormTestArgumentsObject extends ConfigFormBase {
|
|||
|
||||
$form['bananas'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => SafeMarkup::checkPlain($arg),
|
||||
'#default_value' => $arg,
|
||||
'#title' => $this->t('Bananas'),
|
||||
);
|
||||
|
||||
|
|
|
@ -4,3 +4,9 @@ httpkernel_test.empty:
|
|||
_controller: '\Drupal\httpkernel_test\Controller\TestController::get'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
httpkernel_test.teapot:
|
||||
path: '/httpkernel-test/teapot'
|
||||
defaults:
|
||||
_controller: '\Drupal\httpkernel_test\Controller\TestController::teapot'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -21,4 +21,21 @@ class TestController {
|
|||
return new Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test special header and status code rendering.
|
||||
*
|
||||
* @return array
|
||||
* A render array using features of the 'http_header' directive.
|
||||
*/
|
||||
public function teapot() {
|
||||
$render = [];
|
||||
$render['#attached']['http_header'][] = ['X-Test-Teapot-Replace', 'This value gets replaced'];
|
||||
$render['#attached']['http_header'][] = ['X-Test-Teapot-Replace', 'Teapot replaced', TRUE];
|
||||
$render['#attached']['http_header'][] = ['X-Test-Teapot-No-Replace', 'This value is not replaced'];
|
||||
$render['#attached']['http_header'][] = ['X-Test-Teapot-No-Replace', 'This one is added', FALSE];
|
||||
$render['#attached']['http_header'][] = ['X-Test-Teapot', 'Teapot Mode Active'];
|
||||
$render['#attached']['http_header'][] = ['Status', "418 I'm a teapot."];
|
||||
return $render;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Schema for the configuration files of the Image Test module.
|
||||
|
||||
system.image.test_toolkit:
|
||||
type: mapping
|
||||
type: config_object
|
||||
label: 'Image test toolkit'
|
||||
mapping:
|
||||
test_parameter:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Schema for the configuration files of the Hook Menu Test module.
|
||||
|
||||
menu_test.menu_item:
|
||||
type: mapping
|
||||
type: config_object
|
||||
label: 'Menu test'
|
||||
mapping:
|
||||
title:
|
||||
|
|
|
@ -27,9 +27,9 @@ function menu_test_menu_links_discovered_alter(&$links) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu_local_tasks().
|
||||
* Implements hook_menu_local_tasks_alter().
|
||||
*/
|
||||
function menu_test_menu_local_tasks(&$data, $route_name) {
|
||||
function menu_test_menu_local_tasks_alter(&$data, $route_name) {
|
||||
if (in_array($route_name, array('menu_test.tasks_default'))) {
|
||||
$data['tabs'][0]['foo'] = array(
|
||||
'#theme' => 'menu_local_task',
|
||||
|
@ -50,32 +50,6 @@ function menu_test_menu_local_tasks(&$data, $route_name) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu_local_tasks_alter().
|
||||
*
|
||||
* If the menu_test.settings configuration 'tasks.alter' has been set, adds
|
||||
* several local tasks to menu-test/tasks.
|
||||
*/
|
||||
function menu_test_menu_local_tasks_alter(&$data, $route_name) {
|
||||
if (!\Drupal::config('menu_test.settings')->get('tasks.alter')) {
|
||||
return;
|
||||
}
|
||||
if (in_array($route_name, array('menu_test.tasks_default', 'menu_test.tasks_empty', 'menu_test.tasks_tasks'))) {
|
||||
// Rename the default local task from 'View' to 'Show'.
|
||||
// $data['tabs'] is expected to be keyed by link hrefs.
|
||||
// The default local task always links to its parent path, which means that
|
||||
// if the tab root path appears as key in $data['tabs'], then that key is
|
||||
// the default local task.
|
||||
$key = $route_name . '_tab';
|
||||
if (isset($data['tabs'][0][$key])) {
|
||||
$data['tabs'][0][$key]['#link']['title'] = 'Show it';
|
||||
}
|
||||
// Rename the 'foo' task to "Advanced settings" and put it last.
|
||||
$data['tabs'][0]['foo']['#link']['title'] = 'Advanced settings';
|
||||
$data['tabs'][0]['foo']['#weight'] = 110;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback: Tests the theme negotiation functionality.
|
||||
*
|
||||
|
|
|
@ -57,7 +57,7 @@ class TestControllers {
|
|||
return ['#markup' => SafeMarkup::format("Sometimes there is a placeholder: '@placeholder'.", array('@placeholder' => $placeholder))];
|
||||
}
|
||||
else {
|
||||
return ['#markup' => SafeMarkup::format('Sometimes there is no placeholder.')];
|
||||
return ['#markup' => 'Sometimes there is no placeholder.'];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
name: module handler test multiple
|
||||
type: module
|
||||
description: Test module used to test adding modules with child module.
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
hidden: true
|
|
@ -0,0 +1,7 @@
|
|||
name: module handler test multiple child
|
||||
type: module
|
||||
description: Child of test module used to test adding modules with child module.
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
hidden: true
|
|
@ -10,6 +10,7 @@ namespace Drupal\system_test\Controller;
|
|||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Render\SafeString;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
@ -101,7 +102,7 @@ class SystemTestController extends ControllerBase {
|
|||
public function drupalSetMessageTest() {
|
||||
// Set two messages.
|
||||
drupal_set_message('First message (removed).');
|
||||
drupal_set_message('Second message (not removed).');
|
||||
drupal_set_message(t('Second message with <em>markup!</em> (not removed).'));
|
||||
|
||||
// Remove the first.
|
||||
unset($_SESSION['messages']['status'][0]);
|
||||
|
@ -112,6 +113,23 @@ class SystemTestController extends ControllerBase {
|
|||
|
||||
drupal_set_message('Duplicated message', 'status', TRUE);
|
||||
drupal_set_message('Duplicated message', 'status', TRUE);
|
||||
|
||||
// Add a SafeString message.
|
||||
drupal_set_message(SafeString::create('SafeString with <em>markup!</em>'));
|
||||
// Test duplicate SafeString messages.
|
||||
drupal_set_message(SafeString::create('SafeString with <em>markup!</em>'));
|
||||
// Ensure that multiple SafeString messages work.
|
||||
drupal_set_message(SafeString::create('SafeString2 with <em>markup!</em>'));
|
||||
|
||||
// Test mixing of types.
|
||||
drupal_set_message(SafeString::create('Non duplicate SafeString / string.'));
|
||||
drupal_set_message('Non duplicate SafeString / string.');
|
||||
drupal_set_message(SafeString::create('Duplicate SafeString / string.'), 'status', TRUE);
|
||||
drupal_set_message('Duplicate SafeString / string.', 'status', TRUE);
|
||||
|
||||
// Test auto-escape of non safe strings.
|
||||
drupal_set_message('<em>This<span>markup will be</span> escaped</em>.');
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\test_page_test\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Html;
|
||||
|
||||
/**
|
||||
* Defines a test controller for page titles.
|
||||
|
@ -54,19 +54,13 @@ class Test {
|
|||
/**
|
||||
* Defines a controller with a cached render array.
|
||||
*
|
||||
* @param bool $mark_safe
|
||||
* Whether or not to mark the title as safe use SafeMarkup::checkPlain.
|
||||
*
|
||||
* @return array
|
||||
* A render array
|
||||
*/
|
||||
public function controllerWithCache($mark_safe = FALSE) {
|
||||
public function controllerWithCache() {
|
||||
$build = [];
|
||||
$build['#title'] = '<span>Cached title</span>';
|
||||
if ($mark_safe) {
|
||||
$build['#title'] = SafeMarkup::checkPlain($build['#title']);
|
||||
}
|
||||
$build['#cache']['keys'] = ['test_controller', 'with_title', $mark_safe];
|
||||
$build['#cache']['keys'] = ['test_controller', 'with_title'];
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
|
|
@ -2,3 +2,7 @@ test_page_test.test_page:
|
|||
route_name: test_page_test.test_page
|
||||
title: 'Test front page link'
|
||||
weight: 0
|
||||
test_page_test.front_page:
|
||||
title: 'Home'
|
||||
route_name: '<front>'
|
||||
menu_name: main
|
||||
|
|
|
@ -28,14 +28,6 @@ test_page_test.cached_controller:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
test_page_test.cached_controller.safe:
|
||||
path: '/test-page-cached-controller-safe'
|
||||
defaults:
|
||||
_controller: '\Drupal\test_page_test\Controller\Test::controllerWithCache'
|
||||
mark_safe: true
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
test_page_test.dynamic_title:
|
||||
path: '/test-page-dynamic-title'
|
||||
defaults:
|
||||
|
|
|
@ -143,4 +143,25 @@ class ThemeTestController extends ControllerBase {
|
|||
return new JsonResponse(['theme_initialized' => $theme_initialized]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller for testing preprocess functions with theme suggestions.
|
||||
*/
|
||||
public function preprocessSuggestions() {
|
||||
return [
|
||||
[
|
||||
'#theme' => 'theme_test_preprocess_suggestions',
|
||||
'#foo' => 'suggestion',
|
||||
],
|
||||
[
|
||||
'#theme' => 'theme_test_preprocess_suggestions',
|
||||
'#foo' => 'kitten',
|
||||
],
|
||||
[
|
||||
'#theme' => 'theme_test_preprocess_suggestions',
|
||||
'#foo' => 'monkey',
|
||||
],
|
||||
['#theme' => 'theme_test_preprocess_suggestions__kitten__flamingo'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<div class="suggestion">{{ foo }}</div>
|
||||
{% if bar %}
|
||||
<div class="suggestion">{{ bar }}</div>
|
||||
{% endif %}
|
|
@ -55,6 +55,12 @@ function theme_test_theme($existing, $type, $theme, $path) {
|
|||
$info['test_theme_not_existing_function'] = array(
|
||||
'function' => 'test_theme_not_existing_function',
|
||||
);
|
||||
$items['theme_test_preprocess_suggestions'] = [
|
||||
'variables' => [
|
||||
'foo' => '',
|
||||
'bar' => '',
|
||||
],
|
||||
];
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
@ -89,6 +95,27 @@ function theme_theme_test_function_template_override($variables) {
|
|||
return 'theme_test_function_template_override test failed.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme_suggestions_HOOK().
|
||||
*/
|
||||
function theme_test_theme_suggestions_theme_test_preprocess_suggestions($variables) {
|
||||
return ['theme_test_preprocess_suggestions__' . $variables['foo']];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_preprocess_HOOK().
|
||||
*/
|
||||
function theme_test_preprocess_theme_test_preprocess_suggestions(&$variables) {
|
||||
$variables['foo'] = 'Theme hook implementor=theme_theme_test_preprocess_suggestions().';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a module overriding a default hook with a suggestion.
|
||||
*/
|
||||
function theme_test_preprocess_theme_test_preprocess_suggestions__monkey(&$variables) {
|
||||
$variables['foo'] = 'Monkey';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares variables for test render element templates.
|
||||
*
|
||||
|
|
|
@ -103,3 +103,10 @@ theme_test.non_html:
|
|||
_controller: '\Drupal\theme_test\ThemeTestController::nonHtml'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
theme_test.preprocess_suggestions:
|
||||
path: '/theme-test/preprocess-suggestions'
|
||||
defaults:
|
||||
_controller: '\Drupal\theme_test\ThemeTestController::preprocessSuggestions'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -7,10 +7,13 @@
|
|||
|
||||
namespace Drupal\twig_extension_test;
|
||||
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Controller routines for Twig extension test routes.
|
||||
*/
|
||||
class TwigExtensionTestController {
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Menu callback for testing Twig filters in a Twig template.
|
||||
|
@ -19,6 +22,11 @@ class TwigExtensionTestController {
|
|||
return array(
|
||||
'#theme' => 'twig_extension_test_filter',
|
||||
'#message' => 'Every animal is not a mineral.',
|
||||
'#safe_join_items' => [
|
||||
'<em>will be escaped</em>',
|
||||
$this->t('<em>will be markup</em>'),
|
||||
['#markup' => '<strong>will be rendered</strong>']
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
<div class="testfilter">
|
||||
{{ message|testfilter }}
|
||||
</div>
|
||||
<div>
|
||||
{{ safe_join_items|safe_join('<br/>') }}
|
||||
</div>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
function twig_extension_test_theme($existing, $type, $theme, $path) {
|
||||
return array(
|
||||
'twig_extension_test_filter' => array(
|
||||
'variables' => array('message' => NULL),
|
||||
'variables' => array('message' => NULL, 'safe_join_items' => NULL),
|
||||
'template' => 'twig_extension_test.filter',
|
||||
),
|
||||
'twig_extension_test_function' => array(
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\update_script_test\PathProcessor\BrokenInboundPathProcessor.
|
||||
*/
|
||||
|
||||
namespace Drupal\update_script_test\PathProcessor;
|
||||
|
||||
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
|
||||
use Drupal\Core\State\StateInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Example path processor which breaks on inbound.
|
||||
*/
|
||||
class BrokenInboundPathProcessor implements InboundPathProcessorInterface {
|
||||
|
||||
/**
|
||||
* The state.
|
||||
*
|
||||
* @var \Drupal\Core\State\StateInterface
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Constructs a new BrokenInboundPathProcessor instance.
|
||||
*
|
||||
* @param \Drupal\Core\State\StateInterface $state
|
||||
* The state.
|
||||
*/
|
||||
public function __construct(StateInterface $state) {
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function processInbound($path, Request $request) {
|
||||
if ($this->state->get('update_script_test_broken_inbound', FALSE)) {
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
else {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
services:
|
||||
update_script_test.broken_path_processor:
|
||||
class: Drupal\update_script_test\PathProcessor\BrokenInboundPathProcessor
|
||||
arguments: ['@state']
|
||||
tags:
|
||||
- { name: path_processor_inbound, priority: 1000 }
|
||||
|
|
@ -35,7 +35,14 @@ if ($schema_version >= 8001) {
|
|||
* Schema version 8001.
|
||||
*/
|
||||
function update_test_schema_update_8001() {
|
||||
$table = [
|
||||
'fields' => [
|
||||
'a' => ['type' => 'int', 'not null' => TRUE],
|
||||
'b' => ['type' => 'blob', 'not null' => FALSE],
|
||||
],
|
||||
];
|
||||
|
||||
// Add a column.
|
||||
db_add_index('update_test_schema_table', 'test', ['a']);
|
||||
db_add_index('update_test_schema_table', 'test', ['a'], $table);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Tests\Extension\ModuleHandlerTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Extension;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use \Drupal\Core\Extension\ModuleUninstallValidatorException;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests ModuleHandler functionality.
|
||||
*
|
||||
* @group Extension
|
||||
*/
|
||||
class ModuleHandlerTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// @todo ModuleInstaller calls system_rebuild_module_data which is part of
|
||||
// system.module, see https://www.drupal.org/node/2208429.
|
||||
include_once $this->root . '/core/modules/system/system.module';
|
||||
|
||||
// Set up the state values so we know where to find the files when running
|
||||
// drupal_get_filename().
|
||||
// @todo Remove as part of https://www.drupal.org/node/2186491
|
||||
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.
|
||||
*/
|
||||
function testModuleList() {
|
||||
$module_list = array();
|
||||
|
||||
$this->assertModuleList($module_list, 'Initial');
|
||||
|
||||
// Try to install a new module.
|
||||
$this->moduleInstaller()->install(array('ban'));
|
||||
$module_list[] = 'ban';
|
||||
sort($module_list);
|
||||
$this->assertModuleList($module_list, 'After adding a module');
|
||||
|
||||
// Try to mess with the module weights.
|
||||
module_set_weight('ban', 20);
|
||||
|
||||
// Move ban to the end of the array.
|
||||
unset($module_list[array_search('ban', $module_list)]);
|
||||
$module_list[] = 'ban';
|
||||
$this->assertModuleList($module_list, 'After changing weights');
|
||||
|
||||
// Test the fixed list feature.
|
||||
$fixed_list = array(
|
||||
'system' => 'core/modules/system/system.module',
|
||||
'menu' => 'core/modules/menu/menu.module',
|
||||
);
|
||||
$this->moduleHandler()->setModuleList($fixed_list);
|
||||
$new_module_list = array_combine(array_keys($fixed_list), array_keys($fixed_list));
|
||||
$this->assertModuleList($new_module_list, t('When using a fixed list'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the extension handler returns the expected values.
|
||||
*
|
||||
* @param array $expected_values
|
||||
* The expected values, sorted by weight and module name.
|
||||
* @param $condition
|
||||
*/
|
||||
protected function assertModuleList(Array $expected_values, $condition) {
|
||||
$expected_values = array_values(array_unique($expected_values));
|
||||
$enabled_modules = array_keys($this->container->get('module_handler')->getModuleList());
|
||||
$this->assertEqual($expected_values, $enabled_modules, format_string('@condition: extension handler returns correct results', array('@condition' => $condition)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests dependency resolution.
|
||||
*
|
||||
* Intentionally using fake dependencies added via hook_system_info_alter()
|
||||
* for modules that normally do not have any dependencies.
|
||||
*
|
||||
* To simplify things further, all of the manipulated modules are either
|
||||
* purely UI-facing or live at the "bottom" of all dependency chains.
|
||||
*
|
||||
* @see module_test_system_info_alter()
|
||||
* @see https://www.drupal.org/files/issues/dep.gv__0.png
|
||||
*/
|
||||
function testDependencyResolution() {
|
||||
$this->enableModules(array('module_test'));
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('module_test'), 'Test module is enabled.');
|
||||
|
||||
// Ensure that modules are not enabled.
|
||||
$this->assertFalse($this->moduleHandler()->moduleExists('color'), 'Color module is disabled.');
|
||||
$this->assertFalse($this->moduleHandler()->moduleExists('config'), 'Config module is disabled.');
|
||||
$this->assertFalse($this->moduleHandler()->moduleExists('help'), 'Help module is disabled.');
|
||||
|
||||
// Create a missing fake dependency.
|
||||
// Color will depend on Config, which depends on a non-existing module Foo.
|
||||
// Nothing should be installed.
|
||||
\Drupal::state()->set('module_test.dependency', 'missing dependency');
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
try {
|
||||
$result = $this->moduleInstaller()->install(array('color'));
|
||||
$this->fail(t('ModuleInstaller::install() throws an exception if dependencies are missing.'));
|
||||
}
|
||||
catch (\Drupal\Core\Extension\MissingDependencyException $e) {
|
||||
$this->pass(t('ModuleInstaller::install() throws an exception if dependencies are missing.'));
|
||||
}
|
||||
|
||||
$this->assertFalse($this->moduleHandler()->moduleExists('color'), 'ModuleHandler::install() aborts if dependencies are missing.');
|
||||
|
||||
// Fix the missing dependency.
|
||||
// Color module depends on Config. Config depends on Help module.
|
||||
\Drupal::state()->set('module_test.dependency', 'dependency');
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
$result = $this->moduleInstaller()->install(array('color'));
|
||||
$this->assertTrue($result, 'ModuleHandler::install() returns the correct value.');
|
||||
|
||||
// Verify that the fake dependency chain was installed.
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('config') && $this->moduleHandler()->moduleExists('help'), 'Dependency chain was installed.');
|
||||
|
||||
// Verify that the original module was installed.
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('color'), 'Module installation with dependencies succeeded.');
|
||||
|
||||
// Verify that the modules were enabled in the correct order.
|
||||
$module_order = \Drupal::state()->get('module_test.install_order') ?: array();
|
||||
$this->assertEqual($module_order, array('help', 'config', 'color'));
|
||||
|
||||
// Uninstall all three modules explicitly, but in the incorrect order,
|
||||
// and make sure that ModuleHandler::uninstall() uninstalled them in the
|
||||
// correct sequence.
|
||||
$result = $this->moduleInstaller()->uninstall(array('config', 'help', 'color'));
|
||||
$this->assertTrue($result, 'ModuleHandler::uninstall() returned TRUE.');
|
||||
|
||||
foreach (array('color', 'config', 'help') as $module) {
|
||||
$this->assertEqual(drupal_get_installed_schema_version($module), SCHEMA_UNINSTALLED, "$module module was uninstalled.");
|
||||
}
|
||||
$uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: array();
|
||||
$this->assertEqual($uninstalled_modules, array('color', 'config', 'help'), 'Modules were uninstalled in the correct order.');
|
||||
|
||||
// Enable Color module again, which should enable both the Config module and
|
||||
// Help module. But, this time do it with Config module declaring a
|
||||
// dependency on a specific version of Help module in its info file. Make
|
||||
// sure that Drupal\Core\Extension\ModuleHandler::install() still works.
|
||||
\Drupal::state()->set('module_test.dependency', 'version dependency');
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
$result = $this->moduleInstaller()->install(array('color'));
|
||||
$this->assertTrue($result, 'ModuleHandler::install() returns the correct value.');
|
||||
|
||||
// Verify that the fake dependency chain was installed.
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('config') && $this->moduleHandler()->moduleExists('help'), 'Dependency chain was installed.');
|
||||
|
||||
// Verify that the original module was installed.
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('color'), 'Module installation with version dependencies succeeded.');
|
||||
|
||||
// Finally, verify that the modules were enabled in the correct order.
|
||||
$enable_order = \Drupal::state()->get('module_test.install_order') ?: array();
|
||||
$this->assertIdentical($enable_order, array('help', 'config', 'color'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests uninstalling a module that is a "dependency" of a profile.
|
||||
*/
|
||||
function testUninstallProfileDependency() {
|
||||
$profile = 'minimal';
|
||||
$dependency = 'dblog';
|
||||
$this->setSetting('install_profile', $profile);
|
||||
// Prime the drupal_get_filename() static cache with the location of the
|
||||
// minimal profile as it is not the currently active profile and we don't
|
||||
// yet have any cached way to retrieve its location.
|
||||
// @todo Remove as part of https://www.drupal.org/node/2186491
|
||||
drupal_get_filename('profile', $profile, 'core/profiles/' . $profile . '/' . $profile . '.info.yml');
|
||||
$this->enableModules(array('module_test', $profile));
|
||||
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
$data = system_rebuild_module_data();
|
||||
$this->assertTrue(isset($data[$profile]->requires[$dependency]));
|
||||
|
||||
$this->moduleInstaller()->install(array($dependency));
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists($dependency));
|
||||
|
||||
// Uninstall the profile module "dependency".
|
||||
$result = $this->moduleInstaller()->uninstall(array($dependency));
|
||||
$this->assertTrue($result, 'ModuleHandler::uninstall() returns TRUE.');
|
||||
$this->assertFalse($this->moduleHandler()->moduleExists($dependency));
|
||||
$this->assertEqual(drupal_get_installed_schema_version($dependency), SCHEMA_UNINSTALLED, "$dependency module was uninstalled.");
|
||||
|
||||
// Verify that the installation profile itself was not uninstalled.
|
||||
$uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: array();
|
||||
$this->assertTrue(in_array($dependency, $uninstalled_modules), "$dependency module is in the list of uninstalled modules.");
|
||||
$this->assertFalse(in_array($profile, $uninstalled_modules), 'The installation profile is not in the list of uninstalled modules.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests uninstalling a module that has content.
|
||||
*/
|
||||
function testUninstallContentDependency() {
|
||||
$this->enableModules(array('module_test', 'entity_test', 'text', 'user', 'help'));
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('entity_test'), 'Test module is enabled.');
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('module_test'), 'Test module is enabled.');
|
||||
|
||||
$this->installSchema('user', 'users_data');
|
||||
$entity_types = \Drupal::entityManager()->getDefinitions();
|
||||
foreach ($entity_types as $entity_type) {
|
||||
if ('entity_test' == $entity_type->getProvider()) {
|
||||
$this->installEntitySchema($entity_type->id());
|
||||
}
|
||||
}
|
||||
|
||||
// Create a fake dependency.
|
||||
// entity_test will depend on help. This way help can not be uninstalled
|
||||
// when there is test content preventing entity_test from being uninstalled.
|
||||
\Drupal::state()->set('module_test.dependency', 'dependency');
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
// Create an entity so that the modules can not be disabled.
|
||||
$entity = entity_create('entity_test', array('name' => $this->randomString()));
|
||||
$entity->save();
|
||||
|
||||
// Uninstalling entity_test is not possible when there is content.
|
||||
try {
|
||||
$message = 'ModuleHandler::uninstall() throws ModuleUninstallValidatorException upon uninstalling a module which does not pass validation.';
|
||||
$this->moduleInstaller()->uninstall(array('entity_test'));
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (ModuleUninstallValidatorException $e) {
|
||||
$this->pass(get_class($e) . ': ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// Uninstalling help needs entity_test to be un-installable.
|
||||
try {
|
||||
$message = 'ModuleHandler::uninstall() throws ModuleUninstallValidatorException upon uninstalling a module which does not pass validation.';
|
||||
$this->moduleInstaller()->uninstall(array('help'));
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (ModuleUninstallValidatorException $e) {
|
||||
$this->pass(get_class($e) . ': ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// Deleting the entity.
|
||||
$entity->delete();
|
||||
|
||||
$result = $this->moduleInstaller()->uninstall(array('help'));
|
||||
$this->assertTrue($result, 'ModuleHandler::uninstall() returns TRUE.');
|
||||
$this->assertEqual(drupal_get_installed_schema_version('entity_test'), SCHEMA_UNINSTALLED, "entity_test module was uninstalled.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the correct module metadata is returned.
|
||||
*/
|
||||
function testModuleMetaData() {
|
||||
// Generate the list of available modules.
|
||||
$modules = system_rebuild_module_data();
|
||||
// Check that the mtime field exists for the system module.
|
||||
$this->assertTrue(!empty($modules['system']->info['mtime']), 'The system.info.yml file modification time field is present.');
|
||||
// Use 0 if mtime isn't present, to avoid an array index notice.
|
||||
$test_mtime = !empty($modules['system']->info['mtime']) ? $modules['system']->info['mtime'] : 0;
|
||||
// Ensure the mtime field contains a number that is greater than zero.
|
||||
$this->assertTrue(is_numeric($test_mtime) && ($test_mtime > 0), 'The system.info.yml file modification time field contains a timestamp.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether module-provided stream wrappers are registered properly.
|
||||
*/
|
||||
public function testModuleStreamWrappers() {
|
||||
// file_test.module provides (among others) a 'dummy' stream wrapper.
|
||||
// Verify that it is not registered yet to prevent false positives.
|
||||
$stream_wrappers = \Drupal::service('stream_wrapper_manager')->getWrappers();
|
||||
$this->assertFalse(isset($stream_wrappers['dummy']));
|
||||
$this->moduleInstaller()->install(['file_test']);
|
||||
// Verify that the stream wrapper is available even without calling
|
||||
// \Drupal::service('stream_wrapper_manager')->getWrappers() again.
|
||||
// If the stream wrapper is not available file_exists() will raise a notice.
|
||||
file_exists('dummy://');
|
||||
$stream_wrappers = \Drupal::service('stream_wrapper_manager')->getWrappers();
|
||||
$this->assertTrue(isset($stream_wrappers['dummy']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the correct theme metadata is returned.
|
||||
*/
|
||||
function testThemeMetaData() {
|
||||
// Generate the list of available themes.
|
||||
$themes = \Drupal::service('theme_handler')->rebuildThemeData();
|
||||
// Check that the mtime field exists for the bartik theme.
|
||||
$this->assertTrue(!empty($themes['bartik']->info['mtime']), 'The bartik.info.yml file modification time field is present.');
|
||||
// Use 0 if mtime isn't present, to avoid an array index notice.
|
||||
$test_mtime = !empty($themes['bartik']->info['mtime']) ? $themes['bartik']->info['mtime'] : 0;
|
||||
// Ensure the mtime field contains a number that is greater than zero.
|
||||
$this->assertTrue(is_numeric($test_mtime) && ($test_mtime > 0), 'The bartik.info.yml file modification time field contains a timestamp.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ModuleHandler.
|
||||
*
|
||||
* @return \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected function moduleHandler() {
|
||||
return $this->container->get('module_handler');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ModuleInstaller.
|
||||
*
|
||||
* @return \Drupal\Core\Extension\ModuleInstallerInterface
|
||||
*/
|
||||
protected function moduleInstaller() {
|
||||
return $this->container->get('module_installer');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Tests\PhpStorage\PhpStorageFactoryTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\PhpStorage;
|
||||
|
||||
use Drupal\Component\PhpStorage\MTimeProtectedFileStorage;
|
||||
use Drupal\Core\PhpStorage\PhpStorageFactory;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\StreamWrapper\PublicStream;
|
||||
use Drupal\system\PhpStorage\MockPhpStorage;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the PHP storage factory.
|
||||
*
|
||||
* @group PhpStorage
|
||||
* @see \Drupal\Core\PhpStorage\PhpStorageFactory
|
||||
*/
|
||||
class PhpStorageFactoryTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Empty the PHP storage settings, as KernelTestBase sets it by default.
|
||||
$settings = Settings::getAll();
|
||||
unset($settings['php_storage']);
|
||||
new Settings($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the get() method with no settings.
|
||||
*/
|
||||
public function testGetNoSettings() {
|
||||
$php = PhpStorageFactory::get('test');
|
||||
// This should be the default class used.
|
||||
$this->assertTrue($php instanceof MTimeProtectedFileStorage, 'An MTimeProtectedFileStorage instance was returned with no settings.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the get() method using the 'default' settings.
|
||||
*/
|
||||
public function testGetDefault() {
|
||||
$this->setSettings();
|
||||
$php = PhpStorageFactory::get('test');
|
||||
$this->assertTrue($php instanceof MockPhpStorage, 'A FileReadOnlyStorage instance was returned with default settings.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the get() method with overridden settings.
|
||||
*/
|
||||
public function testGetOverride() {
|
||||
$this->setSettings('test');
|
||||
$php = PhpStorageFactory::get('test');
|
||||
// The FileReadOnlyStorage should be used from settings.
|
||||
$this->assertTrue($php instanceof MockPhpStorage, 'A MockPhpStorage instance was returned from overridden settings.');
|
||||
|
||||
// Test that the name is used for the bin when it is NULL.
|
||||
$this->setSettings('test', array('bin' => NULL));
|
||||
$php = PhpStorageFactory::get('test');
|
||||
$this->assertTrue($php instanceof MockPhpStorage, 'An MockPhpStorage instance was returned from overridden settings.');
|
||||
$this->assertIdentical('test', $php->getConfigurationValue('bin'), 'Name value was used for bin.');
|
||||
|
||||
// Test that a default directory is set if it's empty.
|
||||
$this->setSettings('test', array('directory' => NULL));
|
||||
$php = PhpStorageFactory::get('test');
|
||||
$this->assertTrue($php instanceof MockPhpStorage, 'An MockPhpStorage instance was returned from overridden settings.');
|
||||
$this->assertIdentical(PublicStream::basePath() . '/php', $php->getConfigurationValue('directory'), 'Default file directory was used.');
|
||||
|
||||
// Test that a default storage class is set if it's empty.
|
||||
$this->setSettings('test', array('class' => NULL));
|
||||
$php = PhpStorageFactory::get('test');
|
||||
$this->assertTrue($php instanceof MTimeProtectedFileStorage, 'An MTimeProtectedFileStorage instance was returned from overridden settings with no class.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Settings() singleton.
|
||||
*
|
||||
* @param string $name
|
||||
* The storage bin name to set.
|
||||
* @param array $configuration
|
||||
* An array of configuration to set. Will be merged with default values.
|
||||
*/
|
||||
protected function setSettings($name = 'default', array $configuration = array()) {
|
||||
$settings['php_storage'][$name] = $configuration + array(
|
||||
'class' => 'Drupal\system\PhpStorage\MockPhpStorage',
|
||||
'directory' => 'tmp://',
|
||||
'secret' => $this->randomString(),
|
||||
'bin' => 'test',
|
||||
);
|
||||
new Settings($settings);
|
||||
}
|
||||
|
||||
}
|
|
@ -7,8 +7,10 @@
|
|||
|
||||
namespace Drupal\Tests\system\Unit\Breadcrumbs;
|
||||
|
||||
use Drupal\Core\Link;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Link;
|
||||
use Drupal\Core\Access\AccessResultAllowed;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Drupal\Core\Url;
|
||||
|
@ -16,6 +18,7 @@ use Drupal\Core\Utility\LinkGeneratorInterface;
|
|||
use Drupal\system\PathBasedBreadcrumbBuilder;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
@ -117,6 +120,15 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
);
|
||||
|
||||
$this->builder->setStringTranslation($this->getStringTranslationStub());
|
||||
|
||||
$cache_contexts_manager = $this->getMockBuilder('Drupal\Core\Cache\Context\CacheContextsManager')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cache_contexts_manager->expects($this->any())
|
||||
->method('validate_tokens');
|
||||
$container = new Container();
|
||||
$container->set('cache_contexts_manager', $cache_contexts_manager);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,8 +141,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
->method('getPathInfo')
|
||||
->will($this->returnValue('/'));
|
||||
|
||||
$links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals(array(), $links);
|
||||
$breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals([], $breadcrumb->getLinks());
|
||||
$this->assertEquals(['url.path'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals([], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,8 +158,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
->method('getPathInfo')
|
||||
->will($this->returnValue('/example'));
|
||||
|
||||
$links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals(array(0 => new Link('Home', new Url('<front>'))), $links);
|
||||
$breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals([0 => new Link('Home', new Url('<front>'))], $breadcrumb->getLinks());
|
||||
$this->assertEquals(['url.path'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals([], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,8 +193,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
|
||||
$this->setupAccessManagerToAllow();
|
||||
|
||||
$links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals(array(0 => new Link('Home', new Url('<front>')), 1 => new Link('Example', new Url('example'))), $links);
|
||||
$breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals([0 => new Link('Home', new Url('<front>')), 1 => new Link('Example', new Url('example'))], $breadcrumb->getLinks());
|
||||
$this->assertEquals(['url.path', 'user.permissions'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals([], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -213,14 +234,21 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
}
|
||||
}));
|
||||
|
||||
$this->setupAccessManagerToAllow();
|
||||
|
||||
$links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals(array(
|
||||
$this->accessManager->expects($this->any())
|
||||
->method('check')
|
||||
->willReturnOnConsecutiveCalls(
|
||||
AccessResult::allowed()->cachePerPermissions(),
|
||||
AccessResult::allowed()->addCacheContexts(['bar'])->addCacheTags(['example'])
|
||||
);
|
||||
$breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals([
|
||||
new Link('Home', new Url('<front>')),
|
||||
new Link('Example', new Url('example')),
|
||||
new Link('Bar', new Url('example_bar')),
|
||||
), $links);
|
||||
], $breadcrumb->getLinks());
|
||||
$this->assertEquals(['bar', 'url.path', 'user.permissions'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals(['example'], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,10 +269,13 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
->method('matchRequest')
|
||||
->will($this->throwException(new $exception_class($exception_argument)));
|
||||
|
||||
$links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
|
||||
// No path matched, though at least the frontpage is displayed.
|
||||
$this->assertEquals(array(0 => new Link('Home', new Url('<front>'))), $links);
|
||||
$this->assertEquals([0 => new Link('Home', new Url('<front>'))], $breadcrumb->getLinks());
|
||||
$this->assertEquals(['url.path'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals([], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -282,10 +313,13 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
->method('matchRequest')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
$links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
|
||||
// No path matched, though at least the frontpage is displayed.
|
||||
$this->assertEquals(array(0 => new Link('Home', new Url('<front>'))), $links);
|
||||
$this->assertEquals([0 => new Link('Home', new Url('<front>'))], $breadcrumb->getLinks());
|
||||
$this->assertEquals(['url.path'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals([], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -329,8 +363,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
->with($this->anything(), $route_1)
|
||||
->will($this->returnValue('Admin'));
|
||||
|
||||
$links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals(array(0 => new Link('Home', new Url('<front>')), 1 => new Link('Admin', new Url('user_page'))), $links);
|
||||
$breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
$this->assertEquals([0 => new Link('Home', new Url('<front>')), 1 => new Link('Admin', new Url('user_page'))], $breadcrumb->getLinks());
|
||||
$this->assertEquals(['url.path', 'user.permissions'], $breadcrumb->getCacheContexts());
|
||||
$this->assertEquals([], $breadcrumb->getCacheTags());
|
||||
$this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -339,7 +376,7 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
public function setupAccessManagerToAllow() {
|
||||
$this->accessManager->expects($this->any())
|
||||
->method('check')
|
||||
->willReturn(TRUE);
|
||||
->willReturn((new AccessResultAllowed())->cachePerPermissions());
|
||||
}
|
||||
|
||||
protected function setupStubPathProcessor() {
|
||||
|
|
|
@ -100,7 +100,10 @@ class MenuLinkTreeTest extends UnitTestCase {
|
|||
*
|
||||
* @dataProvider providerTestBuildCacheability
|
||||
*/
|
||||
public function testBuildCacheability($description, $tree, $expected_build) {
|
||||
public function testBuildCacheability($description, $tree, $expected_build, $access, array $access_cache_contexts = []) {
|
||||
if ($access !== NULL) {
|
||||
$access->addCacheContexts($access_cache_contexts);
|
||||
}
|
||||
$build = $this->menuLinkTree->build($tree);
|
||||
sort($expected_build['#cache']['contexts']);
|
||||
$this->assertEquals($expected_build, $build, $description);
|
||||
|
@ -175,13 +178,12 @@ class MenuLinkTreeTest extends UnitTestCase {
|
|||
'description' => 'Empty tree.',
|
||||
'tree' => [],
|
||||
'expected_build' => $base_expected_build_empty,
|
||||
'access' => NULL,
|
||||
'access_cache_contexts' => [],
|
||||
];
|
||||
|
||||
for ($i = 0; $i < count($access_scenarios); $i++) {
|
||||
list($access, $access_cache_contexts) = $access_scenarios[$i];
|
||||
if ($access !== NULL) {
|
||||
$access->addCacheContexts($access_cache_contexts);
|
||||
}
|
||||
|
||||
for ($j = 0; $j < count($links_scenarios); $j++) {
|
||||
$links = $links_scenarios[$j];
|
||||
|
@ -203,6 +205,8 @@ class MenuLinkTreeTest extends UnitTestCase {
|
|||
'description' => "Single-item tree; access=$i; link=$j.",
|
||||
'tree' => $tree,
|
||||
'expected_build' => $expected_build,
|
||||
'access' => $access,
|
||||
'access_cache_contexts' => $access_cache_contexts,
|
||||
];
|
||||
|
||||
// Single-level tree.
|
||||
|
@ -221,6 +225,8 @@ class MenuLinkTreeTest extends UnitTestCase {
|
|||
'description' => "Single-level tree; access=$i; link=$j.",
|
||||
'tree' => $tree,
|
||||
'expected_build' => $expected_build,
|
||||
'access' => $access,
|
||||
'access_cache_contexts' => $access_cache_contexts,
|
||||
];
|
||||
|
||||
// Multi-level tree.
|
||||
|
@ -251,6 +257,8 @@ class MenuLinkTreeTest extends UnitTestCase {
|
|||
'description' => "Multi-level tree; access=$i; link=$j.",
|
||||
'tree' => $tree,
|
||||
'expected_build' => $expected_build,
|
||||
'access' => $access,
|
||||
'access_cache_contexts' => $access_cache_contexts,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\system\Unit\Plugin\migrate\source\MenuTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\system\Unit\Plugin\migrate\source;
|
||||
|
||||
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
|
||||
|
||||
/**
|
||||
* Tests menu source plugin.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class MenuTest extends MigrateSqlSourceTestCase {
|
||||
|
||||
const PLUGIN_CLASS = 'Drupal\system\Plugin\migrate\source\Menu';
|
||||
|
||||
protected $migrationConfiguration = array(
|
||||
'id' => 'test',
|
||||
'source' => array(
|
||||
'plugin' => 'menu',
|
||||
),
|
||||
);
|
||||
|
||||
protected $expectedResults = array(
|
||||
array(
|
||||
'menu_name' => 'menu-name-1',
|
||||
'title' => 'menu custom value 1',
|
||||
'description' => 'menu custom description value 1',
|
||||
),
|
||||
array(
|
||||
'menu_name' => 'menu-name-2',
|
||||
'title' => 'menu custom value 2',
|
||||
'description' => 'menu custom description value 2',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->databaseContents['menu_custom'] = $this->expectedResults;
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
* @file
|
||||
* Add hooks for tests to use.
|
||||
*/
|
||||
use Drupal\views\Plugin\views\cache\CachePluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
|
||||
/**
|
||||
|
@ -17,7 +18,7 @@ function test_basetheme_views_pre_render(ViewExecutable $view) {
|
|||
/**
|
||||
* Implements hook_views_post_render().
|
||||
*/
|
||||
function test_basetheme_views_post_render(ViewExecutable $view) {
|
||||
function test_basetheme_views_post_render(ViewExecutable $view, &$output, CachePluginBase $cache) {
|
||||
// We append the function name to the title for test to check for.
|
||||
$view->setTitle($view->getTitle() . ":" . __FUNCTION__);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Add hooks for tests to use.
|
||||
*/
|
||||
|
||||
use Drupal\views\Plugin\views\cache\CachePluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
|
||||
/**
|
||||
|
@ -18,9 +19,12 @@ function test_subtheme_views_pre_render(ViewExecutable $view) {
|
|||
/**
|
||||
* Implements hook_views_post_render().
|
||||
*/
|
||||
function test_subtheme_views_post_render(ViewExecutable $view) {
|
||||
function test_subtheme_views_post_render(ViewExecutable $view, &$output, CachePluginBase $cache) {
|
||||
// We append the function name to the title for test to check for.
|
||||
$view->setTitle($view->getTitle() . ":" . __FUNCTION__);
|
||||
if ($view->id() == 'test_page_display') {
|
||||
$output['#rows'][0]['#title'] = t('%total_rows items found.', array('%total_rows' => $view->total_rows));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<div class="suggestion">{{ foo }}</div>
|
||||
{% if bar %}
|
||||
<div class="suggestion">{{ bar }}</div>
|
||||
{% endif %}
|
|
@ -0,0 +1 @@
|
|||
<div class="suggestion">{{ foo }}</div>
|
|
@ -105,3 +105,47 @@ function test_theme_theme_test_function_suggestions__module_override($variables)
|
|||
function test_theme_theme_registry_alter(&$registry) {
|
||||
$registry['theme_test_template_test']['variables']['additional'] = 'value';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a theme overriding a suggestion of a base theme hook.
|
||||
*/
|
||||
function test_theme_theme_test_preprocess_suggestions__kitten__meerkat($variables) {
|
||||
return 'Theme hook implementor=test_theme_theme_test__suggestion(). Foo=' . $variables['foo'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a theme overriding a default hook with a suggestion.
|
||||
*
|
||||
* Implements hook_preprocess_HOOK().
|
||||
*/
|
||||
function test_theme_preprocess_theme_test_preprocess_suggestions(&$variables) {
|
||||
$variables['foo'] = 'Theme hook implementor=test_theme_preprocess_theme_test_preprocess_suggestions().';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a theme overriding a default hook with a suggestion.
|
||||
*/
|
||||
function test_theme_preprocess_theme_test_preprocess_suggestions__suggestion(&$variables) {
|
||||
$variables['foo'] = 'Suggestion';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a theme overriding a default hook with a suggestion.
|
||||
*/
|
||||
function test_theme_preprocess_theme_test_preprocess_suggestions__kitten(&$variables) {
|
||||
$variables['foo'] = 'Kitten';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a theme overriding a default hook with a suggestion.
|
||||
*/
|
||||
function test_theme_preprocess_theme_test_preprocess_suggestions__kitten__flamingo(&$variables) {
|
||||
$variables['bar'] = 'Flamingo';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a preprocess function with suggestions.
|
||||
*/
|
||||
function test_theme_preprocess_theme_test_preprocess_suggestions__kitten__meerkat__tarsier__moose(&$variables) {
|
||||
$variables['bar'] = 'Moose';
|
||||
}
|
||||
|
|
Reference in a new issue