updated core to 8.6.3
This commit is contained in:
@@ -7,6 +7,7 @@ use Drupal\Core\Config\PreExistingConfigException;
|
||||
use Drupal\Core\Config\UnmetDependenciesException;
|
||||
use Drupal\Core\Access\AccessManagerInterface;
|
||||
use Drupal\Core\Extension\Extension;
|
||||
use Drupal\Core\Extension\InfoParserException;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Extension\ModuleInstallerInterface;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
@@ -143,8 +144,14 @@ class ModulesListForm extends FormBase {
|
||||
];
|
||||
|
||||
// Sort all modules by their names.
|
||||
$modules = system_rebuild_module_data();
|
||||
uasort($modules, 'system_sort_modules_by_info_name');
|
||||
try {
|
||||
$modules = system_rebuild_module_data();
|
||||
uasort($modules, 'system_sort_modules_by_info_name');
|
||||
}
|
||||
catch (InfoParserException $e) {
|
||||
$this->messenger()->addError($this->t('Modules could not be listed due to an error: %error', ['%error' => $e->getMessage()]));
|
||||
$modules = [];
|
||||
}
|
||||
|
||||
// Iterate over each of the modules.
|
||||
$form['modules']['#tree'] = TRUE;
|
||||
|
||||
@@ -144,7 +144,7 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface {
|
||||
|
||||
// Add the url.path.parent cache context. This code ignores the last path
|
||||
// part so the result only depends on the path parents.
|
||||
$breadcrumb->addCacheContexts(['url.path.parent']);
|
||||
$breadcrumb->addCacheContexts(['url.path.parent', 'url.path.is_front']);
|
||||
|
||||
// Do not display a breadcrumb on the frontpage.
|
||||
if ($this->pathMatcher->isFrontPage()) {
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Ajax;
|
||||
|
||||
use Drupal\Core\Ajax\AddCssCommand;
|
||||
use Drupal\Core\Ajax\AfterCommand;
|
||||
use Drupal\Core\Ajax\AjaxResponse;
|
||||
use Drupal\Core\Ajax\AlertCommand;
|
||||
use Drupal\Core\Ajax\AppendCommand;
|
||||
use Drupal\Core\Ajax\BeforeCommand;
|
||||
use Drupal\Core\Ajax\ChangedCommand;
|
||||
use Drupal\Core\Ajax\CssCommand;
|
||||
use Drupal\Core\Ajax\DataCommand;
|
||||
use Drupal\Core\Ajax\HtmlCommand;
|
||||
use Drupal\Core\Ajax\InvokeCommand;
|
||||
use Drupal\Core\Ajax\InsertCommand;
|
||||
use Drupal\Core\Ajax\PrependCommand;
|
||||
use Drupal\Core\Ajax\RemoveCommand;
|
||||
use Drupal\Core\Ajax\RestripeCommand;
|
||||
use Drupal\Core\Ajax\SettingsCommand;
|
||||
use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
|
||||
/**
|
||||
* Performs tests on AJAX framework commands.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class CommandsTest extends AjaxTestBase {
|
||||
|
||||
/**
|
||||
* Tests the various Ajax Commands.
|
||||
*/
|
||||
public function testAjaxCommands() {
|
||||
$form_path = 'ajax_forms_test_ajax_commands_form';
|
||||
$web_user = $this->drupalCreateUser(['access content']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
$edit = [];
|
||||
|
||||
// Tests the 'add_css' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'add_css' command")]);
|
||||
$expected = new AddCssCommand('my/file.css');
|
||||
$this->assertCommand($commands, $expected->render(), "'add_css' AJAX command issued with correct data.");
|
||||
|
||||
// Tests the 'after' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'After': Click to put something after the div")]);
|
||||
$expected = new AfterCommand('#after_div', 'This will be placed after');
|
||||
$this->assertCommand($commands, $expected->render(), "'after' AJAX command issued with correct data.");
|
||||
|
||||
// Tests the 'alert' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'Alert': Click to alert")]);
|
||||
$expected = new AlertCommand(t('Alert'));
|
||||
$this->assertCommand($commands, $expected->render(), "'alert' AJAX Command issued with correct text.");
|
||||
|
||||
// Tests the 'append' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'Append': Click to append something")]);
|
||||
$expected = new AppendCommand('#append_div', 'Appended text');
|
||||
$this->assertCommand($commands, $expected->render(), "'append' AJAX command issued with correct data.");
|
||||
|
||||
// Tests the 'before' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'before': Click to put something before the div")]);
|
||||
$expected = new BeforeCommand('#before_div', 'Before text');
|
||||
$this->assertCommand($commands, $expected->render(), "'before' AJAX command issued with correct data.");
|
||||
|
||||
// Tests the 'changed' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX changed: Click to mark div changed.")]);
|
||||
$expected = new ChangedCommand('#changed_div');
|
||||
$this->assertCommand($commands, $expected->render(), "'changed' AJAX command issued with correct selector.");
|
||||
|
||||
// Tests the 'changed' command using the second argument.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX changed: Click to mark div changed with asterisk.")]);
|
||||
$expected = new ChangedCommand('#changed_div', '#changed_div_mark_this');
|
||||
$this->assertCommand($commands, $expected->render(), "'changed' AJAX command (with asterisk) issued with correct selector.");
|
||||
|
||||
// Tests the 'css' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("Set the '#box' div to be blue.")]);
|
||||
$expected = new CssCommand('#css_div', ['background-color' => 'blue']);
|
||||
$this->assertCommand($commands, $expected->render(), "'css' AJAX command issued with correct selector.");
|
||||
|
||||
// Tests the 'data' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX data command: Issue command.")]);
|
||||
$expected = new DataCommand('#data_div', 'testkey', 'testvalue');
|
||||
$this->assertCommand($commands, $expected->render(), "'data' AJAX command issued with correct key and value.");
|
||||
|
||||
// Tests the 'html' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX html: Replace the HTML in a selector.")]);
|
||||
$expected = new HtmlCommand('#html_div', 'replacement text');
|
||||
$this->assertCommand($commands, $expected->render(), "'html' AJAX command issued with correct data.");
|
||||
|
||||
// Tests the 'insert' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX insert: Let client insert based on #ajax['method'].")]);
|
||||
$expected = new InsertCommand('#insert_div', 'insert replacement text');
|
||||
$this->assertCommand($commands, $expected->render(), "'insert' AJAX command issued with correct data.");
|
||||
|
||||
// Tests the 'invoke' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX invoke command: Invoke addClass() method.")]);
|
||||
$expected = new InvokeCommand('#invoke_div', 'addClass', ['error']);
|
||||
$this->assertCommand($commands, $expected->render(), "'invoke' AJAX command issued with correct method and argument.");
|
||||
|
||||
// Tests the 'prepend' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'prepend': Click to prepend something")]);
|
||||
$expected = new PrependCommand('#prepend_div', 'prepended text');
|
||||
$this->assertCommand($commands, $expected->render(), "'prepend' AJAX command issued with correct data.");
|
||||
|
||||
// Tests the 'remove' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'remove': Click to remove text")]);
|
||||
$expected = new RemoveCommand('#remove_text');
|
||||
$this->assertCommand($commands, $expected->render(), "'remove' AJAX command issued with correct command and selector.");
|
||||
|
||||
// Tests the 'restripe' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'restripe' command")]);
|
||||
$expected = new RestripeCommand('#restripe_table');
|
||||
$this->assertCommand($commands, $expected->render(), "'restripe' AJAX command issued with correct selector.");
|
||||
|
||||
// Tests the 'settings' command.
|
||||
$commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'settings' command")]);
|
||||
$expected = new SettingsCommand(['ajax_forms_test' => ['foo' => 42]]);
|
||||
$this->assertCommand($commands, $expected->render(), "'settings' AJAX command issued with correct data.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Regression test: Settings command exists regardless of JS aggregation.
|
||||
*/
|
||||
public function testAttachedSettings() {
|
||||
$assert = function ($message) {
|
||||
$response = new AjaxResponse();
|
||||
$response->setAttachments([
|
||||
'library' => ['core/drupalSettings'],
|
||||
'drupalSettings' => ['foo' => 'bar'],
|
||||
]);
|
||||
|
||||
$ajax_response_attachments_processor = \Drupal::service('ajax_response.attachments_processor');
|
||||
$subscriber = new AjaxResponseSubscriber($ajax_response_attachments_processor);
|
||||
$event = new FilterResponseEvent(
|
||||
\Drupal::service('http_kernel'),
|
||||
new Request(),
|
||||
HttpKernelInterface::MASTER_REQUEST,
|
||||
$response
|
||||
);
|
||||
$subscriber->onResponse($event);
|
||||
$expected = [
|
||||
'command' => 'settings',
|
||||
];
|
||||
$this->assertCommand($response->getCommands(), $expected, $message);
|
||||
};
|
||||
|
||||
$config = $this->config('system.performance');
|
||||
|
||||
$config->set('js.preprocess', FALSE)->save();
|
||||
$assert('Settings command exists when JS aggregation is disabled.');
|
||||
|
||||
$config->set('js.preprocess', TRUE)->save();
|
||||
$assert('Settings command exists when JS aggregation is enabled.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Ajax;
|
||||
|
||||
use Drupal\ajax_test\Controller\AjaxTestController;
|
||||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Performs tests on opening and manipulating dialogs via AJAX commands.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class DialogTest extends AjaxTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['ajax_test', 'ajax_forms_test', 'contact'];
|
||||
|
||||
/**
|
||||
* Test sending non-JS and AJAX requests to open and manipulate modals.
|
||||
*/
|
||||
public function testDialog() {
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer contact forms']));
|
||||
// Ensure the elements render without notices or exceptions.
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
|
||||
// Set up variables for this test.
|
||||
$dialog_renderable = AjaxTestController::dialogContents();
|
||||
$dialog_contents = \Drupal::service('renderer')->renderRoot($dialog_renderable);
|
||||
$modal_expected_response = [
|
||||
'command' => 'openDialog',
|
||||
'selector' => '#drupal-modal',
|
||||
'settings' => NULL,
|
||||
'data' => $dialog_contents,
|
||||
'dialogOptions' => [
|
||||
'modal' => TRUE,
|
||||
'title' => 'AJAX Dialog & contents',
|
||||
],
|
||||
];
|
||||
$form_expected_response = [
|
||||
'command' => 'openDialog',
|
||||
'selector' => '#drupal-modal',
|
||||
'settings' => NULL,
|
||||
'dialogOptions' => [
|
||||
'modal' => TRUE,
|
||||
'title' => 'Ajax Form contents',
|
||||
],
|
||||
];
|
||||
$entity_form_expected_response = [
|
||||
'command' => 'openDialog',
|
||||
'selector' => '#drupal-modal',
|
||||
'settings' => NULL,
|
||||
'dialogOptions' => [
|
||||
'modal' => TRUE,
|
||||
'title' => 'Add contact form',
|
||||
],
|
||||
];
|
||||
$normal_expected_response = [
|
||||
'command' => 'openDialog',
|
||||
'selector' => '#ajax-test-dialog-wrapper-1',
|
||||
'settings' => NULL,
|
||||
'data' => $dialog_contents,
|
||||
'dialogOptions' => [
|
||||
'modal' => FALSE,
|
||||
'title' => 'AJAX Dialog & contents',
|
||||
],
|
||||
];
|
||||
$no_target_expected_response = [
|
||||
'command' => 'openDialog',
|
||||
'selector' => '#drupal-dialog-ajax-testdialog-contents',
|
||||
'settings' => NULL,
|
||||
'data' => $dialog_contents,
|
||||
'dialogOptions' => [
|
||||
'modal' => FALSE,
|
||||
'title' => 'AJAX Dialog & contents',
|
||||
],
|
||||
];
|
||||
$close_expected_response = [
|
||||
'command' => 'closeDialog',
|
||||
'selector' => '#ajax-test-dialog-wrapper-1',
|
||||
'persist' => FALSE,
|
||||
];
|
||||
|
||||
// Check that requesting a modal dialog without JS goes to a page.
|
||||
$this->drupalGet('ajax-test/dialog-contents');
|
||||
$this->assertRaw($dialog_contents, 'Non-JS modal dialog page present.');
|
||||
|
||||
// Check that requesting a modal dialog with XMLHttpRequest goes to a page.
|
||||
$this->drupalGetXHR('ajax-test/dialog-contents');
|
||||
$this->assertRaw($dialog_contents, 'Modal dialog page on XMLHttpRequest present.');
|
||||
|
||||
// Emulate going to the JS version of the page and check the JSON response.
|
||||
$ajax_result = $this->drupalGetAjax('ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal']]);
|
||||
$this->assertEqual($modal_expected_response, $ajax_result[3], 'Modal dialog JSON response matches.');
|
||||
// Test the HTML escaping of & character.
|
||||
$this->assertEqual($ajax_result[3]['dialogOptions']['title'], 'AJAX Dialog & contents');
|
||||
$this->assertNotEqual($ajax_result[3]['dialogOptions']['title'], 'AJAX Dialog & contents');
|
||||
|
||||
// Check that requesting a "normal" dialog without JS goes to a page.
|
||||
$this->drupalGet('ajax-test/dialog-contents');
|
||||
$this->assertRaw($dialog_contents, 'Non-JS normal dialog page present.');
|
||||
|
||||
// Emulate going to the JS version of the page and check the JSON response.
|
||||
// This needs to use WebTestBase::drupalPostAjaxForm() so that the correct
|
||||
// dialog options are sent.
|
||||
$ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', [
|
||||
// We have to mock a form element to make drupalPost submit from a link.
|
||||
'textfield' => 'test',
|
||||
], [], 'ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog']], [], NULL, [
|
||||
'submit' => [
|
||||
'dialogOptions[target]' => 'ajax-test-dialog-wrapper-1',
|
||||
],
|
||||
]);
|
||||
$this->assertEqual($normal_expected_response, $ajax_result[3], 'Normal dialog JSON response matches.');
|
||||
|
||||
// Emulate going to the JS version of the page and check the JSON response.
|
||||
// This needs to use WebTestBase::drupalPostAjaxForm() so that the correct
|
||||
// dialog options are sent.
|
||||
$ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', [
|
||||
// We have to mock a form element to make drupalPost submit from a link.
|
||||
'textfield' => 'test',
|
||||
], [], 'ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog']], [], NULL, [
|
||||
// Don't send a target.
|
||||
'submit' => [],
|
||||
]);
|
||||
// Make sure the selector ID starts with the right string.
|
||||
$this->assert(strpos($ajax_result[3]['selector'], $no_target_expected_response['selector']) === 0, 'Selector starts with right string.');
|
||||
unset($ajax_result[3]['selector']);
|
||||
unset($no_target_expected_response['selector']);
|
||||
$this->assertEqual($no_target_expected_response, $ajax_result[3], 'Normal dialog with no target JSON response matches.');
|
||||
|
||||
// Emulate closing the dialog via an AJAX request. There is no non-JS
|
||||
// version of this test.
|
||||
$ajax_result = $this->drupalGetAjax('ajax-test/dialog-close');
|
||||
$this->assertEqual($close_expected_response, $ajax_result[0], 'Close dialog JSON response matches.');
|
||||
|
||||
// Test submitting via a POST request through the button for modals. This
|
||||
// approach more accurately reflects the real responses by Drupal because
|
||||
// all of the necessary page variables are emulated.
|
||||
$ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', [], 'button1');
|
||||
|
||||
// Check that CSS and JavaScript are "added" to the page dynamically.
|
||||
$this->assertTrue(in_array('core/drupal.dialog.ajax', explode(',', $ajax_result[0]['settings']['ajaxPageState']['libraries'])), 'core/drupal.dialog.ajax library is added to the page.');
|
||||
$dialog_css_exists = strpos($ajax_result[1]['data'], 'dialog.css') !== FALSE;
|
||||
$this->assertTrue($dialog_css_exists, 'jQuery UI dialog CSS added to the page.');
|
||||
$dialog_js_exists = strpos($ajax_result[2]['data'], 'dialog-min.js') !== FALSE;
|
||||
$this->assertTrue($dialog_js_exists, 'jQuery UI dialog JS added to the page.');
|
||||
$dialog_js_exists = strpos($ajax_result[2]['data'], 'dialog.ajax.js') !== FALSE;
|
||||
$this->assertTrue($dialog_js_exists, 'Drupal dialog JS added to the page.');
|
||||
|
||||
// Check that the response matches the expected value.
|
||||
$this->assertEqual($modal_expected_response, $ajax_result[4], 'POST request modal dialog JSON response matches.');
|
||||
// Test the HTML escaping of & character.
|
||||
$this->assertNotEqual($ajax_result[4]['dialogOptions']['title'], 'AJAX Dialog & contents');
|
||||
|
||||
// Abbreviated test for "normal" dialogs, testing only the difference.
|
||||
$ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', [], 'button2');
|
||||
$this->assertEqual($normal_expected_response, $ajax_result[4], 'POST request normal dialog JSON response matches.');
|
||||
|
||||
// Check that requesting a form dialog without JS goes to a page.
|
||||
$this->drupalGet('ajax-test/dialog-form');
|
||||
// Check we get a chunk of the code, we can't test the whole form as form
|
||||
// build id and token with be different.
|
||||
$form = $this->xpath("//form[@id='ajax-test-form']");
|
||||
$this->assertTrue(!empty($form), 'Non-JS form page present.');
|
||||
|
||||
// Emulate going to the JS version of the form and check the JSON response.
|
||||
$ajax_result = $this->drupalGetAjax('ajax-test/dialog-form', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal']]);
|
||||
$expected_ajax_settings = [
|
||||
'edit-preview' => [
|
||||
'callback' => '::preview',
|
||||
'event' => 'click',
|
||||
'url' => Url::fromRoute('ajax_test.dialog_form', [], [
|
||||
'query' => [
|
||||
MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal',
|
||||
FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
|
||||
],
|
||||
])->toString(),
|
||||
'dialogType' => 'ajax',
|
||||
'submit' => [
|
||||
'_triggering_element_name' => 'op',
|
||||
'_triggering_element_value' => 'Preview',
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertEqual($expected_ajax_settings, $ajax_result[0]['settings']['ajax']);
|
||||
$this->setRawContent($ajax_result[3]['data']);
|
||||
// Remove the data, the form build id and token will never match.
|
||||
unset($ajax_result[3]['data']);
|
||||
$form = $this->xpath("//form[@id='ajax-test-form']");
|
||||
$this->assertTrue(!empty($form), 'Modal dialog JSON contains form.');
|
||||
$this->assertEqual($form_expected_response, $ajax_result[3]);
|
||||
|
||||
// Check that requesting an entity form dialog without JS goes to a page.
|
||||
$this->drupalGet('admin/structure/contact/add');
|
||||
// Check we get a chunk of the code, we can't test the whole form as form
|
||||
// build id and token with be different.
|
||||
$form = $this->xpath("//form[@id='contact-form-add-form']");
|
||||
$this->assertTrue(!empty($form), 'Non-JS entity form page present.');
|
||||
|
||||
// Emulate going to the JS version of the form and check the JSON response.
|
||||
$ajax_result = $this->drupalGetAjax('admin/structure/contact/add', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal']]);
|
||||
$this->setRawContent($ajax_result[3]['data']);
|
||||
// Remove the data, the form build id and token will never match.
|
||||
unset($ajax_result[3]['data']);
|
||||
$form = $this->xpath("//form[@id='contact-form-add-form']");
|
||||
$this->assertTrue(!empty($form), 'Modal dialog JSON contains entity form.');
|
||||
$this->assertEqual($entity_form_expected_response, $ajax_result[3]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Ajax;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests that AJAX-enabled forms work when multiple instances of the same form
|
||||
* are on a page.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class MultiFormTest extends AjaxTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['form_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']);
|
||||
|
||||
// Create a multi-valued field for 'page' nodes to use for Ajax testing.
|
||||
$field_name = 'field_ajax_test';
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => 'node',
|
||||
'field_name' => $field_name,
|
||||
'type' => 'text',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
])->save();
|
||||
entity_get_form_display('node', 'page', 'default')
|
||||
->setComponent($field_name, ['type' => 'text_textfield'])
|
||||
->save();
|
||||
|
||||
// Log in a user who can create 'page' nodes.
|
||||
$this->drupalLogin($this->drupalCreateUser(['create page content']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that pages with the 'node_page_form' included twice work correctly.
|
||||
*/
|
||||
public function testMultiForm() {
|
||||
// HTML IDs for elements within the field are potentially modified with
|
||||
// each Ajax submission, but these variables are stable and help target the
|
||||
// desired elements.
|
||||
$field_name = 'field_ajax_test';
|
||||
|
||||
$form_xpath = '//form[starts-with(@id, "node-page-form")]';
|
||||
$field_xpath = '//div[contains(@class, "field--name-field-ajax-test")]';
|
||||
$button_name = $field_name . '_add_more';
|
||||
$button_value = t('Add another item');
|
||||
$button_xpath_suffix = '//input[@name="' . $button_name . '"]';
|
||||
$field_items_xpath_suffix = '//input[@type="text"]';
|
||||
|
||||
// Ensure the initial page contains both node forms and the correct number
|
||||
// of field items and "add more" button for the multi-valued field within
|
||||
// each form.
|
||||
$this->drupalGet('form-test/two-instances-of-same-form');
|
||||
|
||||
$fields = $this->xpath($form_xpath . $field_xpath);
|
||||
$this->assertEqual(count($fields), 2);
|
||||
foreach ($fields as $field) {
|
||||
$this->assertEqual(count($field->xpath('.' . $field_items_xpath_suffix)), 1, 'Found the correct number of field items on the initial page.');
|
||||
$this->assertFieldsByValue($field->xpath('.' . $button_xpath_suffix), NULL, 'Found the "add more" button on the initial page.');
|
||||
}
|
||||
|
||||
$this->assertNoDuplicateIds(t('Initial page contains unique IDs'), 'Other');
|
||||
|
||||
// Submit the "add more" button of each form twice. After each corresponding
|
||||
// page update, ensure the same as above.
|
||||
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$forms = $this->xpath($form_xpath);
|
||||
foreach ($forms as $offset => $form) {
|
||||
$form_html_id = (string) $form['id'];
|
||||
$this->drupalPostAjaxForm(NULL, [], [$button_name => $button_value], NULL, [], [], $form_html_id);
|
||||
$form = $this->xpath($form_xpath)[$offset];
|
||||
$field = $form->xpath('.' . $field_xpath);
|
||||
|
||||
$this->assertEqual(count($field[0]->xpath('.' . $field_items_xpath_suffix)), $i + 2, 'Found the correct number of field items after an AJAX submission.');
|
||||
$this->assertFieldsByValue($field[0]->xpath('.' . $button_xpath_suffix), NULL, 'Found the "add more" button after an AJAX submission.');
|
||||
$this->assertNoDuplicateIds(t('Updated page contains unique IDs'), 'Other');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Condition;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests that condition plugins basic form handling is working.
|
||||
*
|
||||
* Checks condition forms and submission and gives a very cursory check to make
|
||||
* sure the configuration that was submitted actually causes the condition to
|
||||
* validate correctly.
|
||||
*
|
||||
* @group Condition
|
||||
*/
|
||||
class ConditionFormTest extends WebTestBase {
|
||||
|
||||
public static $modules = ['node', 'condition_test'];
|
||||
|
||||
/**
|
||||
* Submit the condition_node_type_test_form to test condition forms.
|
||||
*/
|
||||
public function testConfigForm() {
|
||||
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']);
|
||||
$this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
|
||||
|
||||
$article = Node::create([
|
||||
'type' => 'article',
|
||||
'title' => $this->randomMachineName(),
|
||||
]);
|
||||
$article->save();
|
||||
|
||||
$this->drupalGet('condition_test');
|
||||
$this->assertField('bundles[article]', 'There is an article bundle selector.');
|
||||
$this->assertField('bundles[page]', 'There is a page bundle selector.');
|
||||
$this->drupalPostForm(NULL, ['bundles[page]' => 'page', 'bundles[article]' => 'article'], t('Submit'));
|
||||
// @see \Drupal\condition_test\FormController::submitForm()
|
||||
$this->assertText('Bundle: page');
|
||||
$this->assertText('Bundle: article');
|
||||
$this->assertText('Executed successfully.', 'The form configured condition executed properly.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Page;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests default HTML metatags on a page.
|
||||
*
|
||||
* @group Page
|
||||
*/
|
||||
class DefaultMetatagsTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Tests meta tags.
|
||||
*/
|
||||
public function testMetaTag() {
|
||||
$this->drupalGet('');
|
||||
// Ensures that the charset metatag is on the page.
|
||||
$result = $this->xpath('//meta[@charset="utf-8"]');
|
||||
$this->assertEqual(count($result), 1);
|
||||
|
||||
// Ensure that the charset one is the first metatag.
|
||||
$result = $this->xpath('//meta');
|
||||
$this->assertEqual((string) $result[0]->attributes()->charset, 'utf-8');
|
||||
|
||||
// Ensure that the shortcut icon is on the page.
|
||||
$result = $this->xpath('//link[@rel = "shortcut icon"]');
|
||||
$this->assertEqual(count($result), 1, 'The shortcut icon is present.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,320 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Pager;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests pager functionality.
|
||||
*
|
||||
* @group Pager
|
||||
*/
|
||||
class PagerTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['dblog', 'pager_test'];
|
||||
|
||||
/**
|
||||
* A user with permission to access site reports.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
protected $profile = 'testing';
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Insert 300 log messages.
|
||||
$logger = $this->container->get('logger.factory')->get('pager_test');
|
||||
for ($i = 0; $i < 300; $i++) {
|
||||
$logger->debug($this->randomString());
|
||||
}
|
||||
|
||||
$this->adminUser = $this->drupalCreateUser([
|
||||
'access site reports',
|
||||
]);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests markup and CSS classes of pager links.
|
||||
*/
|
||||
public function testActiveClass() {
|
||||
// Verify first page.
|
||||
$this->drupalGet('admin/reports/dblog');
|
||||
$current_page = 0;
|
||||
$this->assertPagerItems($current_page);
|
||||
|
||||
// Verify any page but first/last.
|
||||
$current_page++;
|
||||
$this->drupalGet('admin/reports/dblog', ['query' => ['page' => $current_page]]);
|
||||
$this->assertPagerItems($current_page);
|
||||
|
||||
// Verify last page.
|
||||
$elements = $this->xpath('//li[contains(@class, :class)]/a', [':class' => 'pager__item--last']);
|
||||
preg_match('@page=(\d+)@', $elements[0]['href'], $matches);
|
||||
$current_page = (int) $matches[1];
|
||||
$this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $elements[0]['href'], ['external' => TRUE]);
|
||||
$this->assertPagerItems($current_page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test proper functioning of the query parameters and the pager cache context.
|
||||
*/
|
||||
public function testPagerQueryParametersAndCacheContext() {
|
||||
// First page.
|
||||
$this->drupalGet('pager-test/query-parameters');
|
||||
$this->assertText(t('Pager calls: 0'), 'Initial call to pager shows 0 calls.');
|
||||
$this->assertText('[url.query_args.pagers:0]=0.0');
|
||||
$this->assertCacheContext('url.query_args');
|
||||
|
||||
// Go to last page, the count of pager calls need to go to 1.
|
||||
$elements = $this->xpath('//li[contains(@class, :class)]/a', [':class' => 'pager__item--last']);
|
||||
$this->drupalGet($this->getAbsoluteUrl($elements[0]['href']));
|
||||
$this->assertText(t('Pager calls: 1'), 'First link call to pager shows 1 calls.');
|
||||
$this->assertText('[url.query_args.pagers:0]=0.60');
|
||||
$this->assertCacheContext('url.query_args');
|
||||
|
||||
// Go back to first page, the count of pager calls need to go to 2.
|
||||
$elements = $this->xpath('//li[contains(@class, :class)]/a', [':class' => 'pager__item--first']);
|
||||
$this->drupalGet($this->getAbsoluteUrl($elements[0]['href']));
|
||||
$this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $elements[0]['href'], ['external' => TRUE]);
|
||||
$this->assertText(t('Pager calls: 2'), 'Second link call to pager shows 2 calls.');
|
||||
$this->assertText('[url.query_args.pagers:0]=0.0');
|
||||
$this->assertCacheContext('url.query_args');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test proper functioning of multiple pagers.
|
||||
*/
|
||||
public function testMultiplePagers() {
|
||||
// First page.
|
||||
$this->drupalGet('pager-test/multiple-pagers');
|
||||
|
||||
// Test data.
|
||||
// Expected URL query string param is 0-indexed.
|
||||
// Expected page per pager is 1-indexed.
|
||||
$test_data = [
|
||||
// With no query, all pagers set to first page.
|
||||
[
|
||||
'input_query' => NULL,
|
||||
'expected_page' => [0 => '1', 1 => '1', 4 => '1'],
|
||||
'expected_query' => '?page=0,0,,,0',
|
||||
],
|
||||
// Blanks around page numbers should not be relevant.
|
||||
[
|
||||
'input_query' => '?page=2 , 10,,, 5 ,,',
|
||||
'expected_page' => [0 => '3', 1 => '11', 4 => '6'],
|
||||
'expected_query' => '?page=2,10,,,5',
|
||||
],
|
||||
// Blanks within page numbers should lead to only the first integer
|
||||
// to be considered.
|
||||
[
|
||||
'input_query' => '?page=2 , 3 0,,, 4 13 ,,',
|
||||
'expected_page' => [0 => '3', 1 => '4', 4 => '5'],
|
||||
'expected_query' => '?page=2,3,,,4',
|
||||
],
|
||||
// If floats are passed as page numbers, only the integer part is
|
||||
// returned.
|
||||
[
|
||||
'input_query' => '?page=2.1,6.999,,,5.',
|
||||
'expected_page' => [0 => '3', 1 => '7', 4 => '6'],
|
||||
'expected_query' => '?page=2,6,,,5',
|
||||
],
|
||||
// Partial page fragment, undefined pagers set to first page.
|
||||
[
|
||||
'input_query' => '?page=5,2',
|
||||
'expected_page' => [0 => '6', 1 => '3', 4 => '1'],
|
||||
'expected_query' => '?page=5,2,,,0',
|
||||
],
|
||||
// Partial page fragment, undefined pagers set to first page.
|
||||
[
|
||||
'input_query' => '?page=,2',
|
||||
'expected_page' => [0 => '1', 1 => '3', 4 => '1'],
|
||||
'expected_query' => '?page=0,2,,,0',
|
||||
],
|
||||
// Partial page fragment, undefined pagers set to first page.
|
||||
[
|
||||
'input_query' => '?page=,',
|
||||
'expected_page' => [0 => '1', 1 => '1', 4 => '1'],
|
||||
'expected_query' => '?page=0,0,,,0',
|
||||
],
|
||||
// With overflow pages, all pagers set to max page.
|
||||
[
|
||||
'input_query' => '?page=99,99,,,99',
|
||||
'expected_page' => [0 => '16', 1 => '16', 4 => '16'],
|
||||
'expected_query' => '?page=15,15,,,15',
|
||||
],
|
||||
// Wrong value for the page resets pager to first page.
|
||||
[
|
||||
'input_query' => '?page=bar,5,foo,qux,bet',
|
||||
'expected_page' => [0 => '1', 1 => '6', 4 => '1'],
|
||||
'expected_query' => '?page=0,5,,,0',
|
||||
],
|
||||
];
|
||||
|
||||
// We loop through the page with the test data query parameters, and check
|
||||
// that the active page for each pager element has the expected page
|
||||
// (1-indexed) and resulting query parameter
|
||||
foreach ($test_data as $data) {
|
||||
$input_query = str_replace(' ', '%20', $data['input_query']);
|
||||
$this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $input_query, ['external' => TRUE]);
|
||||
foreach ([0, 1, 4] as $pager_element) {
|
||||
$active_page = $this->cssSelect("div.test-pager-{$pager_element} ul.pager__items li.is-active:contains('{$data['expected_page'][$pager_element]}')");
|
||||
$destination = str_replace('%2C', ',', $active_page[0]->a['href'][0]->__toString());
|
||||
$this->assertEqual($destination, $data['expected_query']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test proper functioning of the ellipsis.
|
||||
*/
|
||||
public function testPagerEllipsis() {
|
||||
// Insert 100 extra log messages to get 9 pages.
|
||||
$logger = $this->container->get('logger.factory')->get('pager_test');
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$logger->debug($this->randomString());
|
||||
}
|
||||
$this->drupalGet('admin/reports/dblog');
|
||||
$elements = $this->cssSelect(".pager__item--ellipsis:contains('…')");
|
||||
$this->assertEqual(count($elements), 0, 'No ellipsis has been set.');
|
||||
|
||||
// Insert an extra 50 log messages to get 10 pages.
|
||||
$logger = $this->container->get('logger.factory')->get('pager_test');
|
||||
for ($i = 0; $i < 50; $i++) {
|
||||
$logger->debug($this->randomString());
|
||||
}
|
||||
$this->drupalGet('admin/reports/dblog');
|
||||
$elements = $this->cssSelect(".pager__item--ellipsis:contains('…')");
|
||||
$this->assertEqual(count($elements), 1, 'Found the ellipsis.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts pager items and links.
|
||||
*
|
||||
* @param int $current_page
|
||||
* The current pager page the internal browser is on.
|
||||
*/
|
||||
protected function assertPagerItems($current_page) {
|
||||
$elements = $this->xpath('//ul[contains(@class, :class)]/li', [':class' => 'pager__items']);
|
||||
$this->assertTrue(!empty($elements), 'Pager found.');
|
||||
|
||||
// Make current page 1-based.
|
||||
$current_page++;
|
||||
|
||||
// Extract first/previous and next/last items.
|
||||
// first/previous only exist, if the current page is not the first.
|
||||
if ($current_page > 1) {
|
||||
$first = array_shift($elements);
|
||||
$previous = array_shift($elements);
|
||||
}
|
||||
// next/last always exist, unless the current page is the last.
|
||||
if ($current_page != count($elements)) {
|
||||
$last = array_pop($elements);
|
||||
$next = array_pop($elements);
|
||||
}
|
||||
|
||||
// We remove elements from the $elements array in the following code, so
|
||||
// we store the total number of pages for verifying the "last" link.
|
||||
$total_pages = count($elements);
|
||||
|
||||
// Verify items and links to pages.
|
||||
foreach ($elements as $page => $element) {
|
||||
// Make item/page index 1-based.
|
||||
$page++;
|
||||
|
||||
if ($current_page == $page) {
|
||||
$this->assertClass($element, 'is-active', 'Element for current page has .is-active class.');
|
||||
$this->assertTrue($element->a, 'Element for current page has link.');
|
||||
$destination = $element->a['href'][0]->__toString();
|
||||
// URL query string param is 0-indexed.
|
||||
$this->assertEqual($destination, '?page=' . ($page - 1));
|
||||
}
|
||||
else {
|
||||
$this->assertNoClass($element, 'is-active', "Element for page $page has no .is-active class.");
|
||||
$this->assertClass($element, 'pager__item', "Element for page $page has .pager__item class.");
|
||||
$this->assertTrue($element->a, "Link to page $page found.");
|
||||
$destination = $element->a['href'][0]->__toString();
|
||||
$this->assertEqual($destination, '?page=' . ($page - 1));
|
||||
}
|
||||
unset($elements[--$page]);
|
||||
}
|
||||
// Verify that no other items remain untested.
|
||||
$this->assertTrue(empty($elements), 'All expected items found.');
|
||||
|
||||
// Verify first/previous and next/last items and links.
|
||||
if (isset($first)) {
|
||||
$this->assertClass($first, 'pager__item--first', 'Element for first page has .pager__item--first class.');
|
||||
$this->assertTrue($first->a, 'Link to first page found.');
|
||||
$this->assertNoClass($first->a, 'is-active', 'Link to first page is not active.');
|
||||
$destination = $first->a['href'][0]->__toString();
|
||||
$this->assertEqual($destination, '?page=0');
|
||||
}
|
||||
if (isset($previous)) {
|
||||
$this->assertClass($previous, 'pager__item--previous', 'Element for first page has .pager__item--previous class.');
|
||||
$this->assertTrue($previous->a, 'Link to previous page found.');
|
||||
$this->assertNoClass($previous->a, 'is-active', 'Link to previous page is not active.');
|
||||
$destination = $previous->a['href'][0]->__toString();
|
||||
// URL query string param is 0-indexed, $current_page is 1-indexed.
|
||||
$this->assertEqual($destination, '?page=' . ($current_page - 2));
|
||||
}
|
||||
if (isset($next)) {
|
||||
$this->assertClass($next, 'pager__item--next', 'Element for next page has .pager__item--next class.');
|
||||
$this->assertTrue($next->a, 'Link to next page found.');
|
||||
$this->assertNoClass($next->a, 'is-active', 'Link to next page is not active.');
|
||||
$destination = $next->a['href'][0]->__toString();
|
||||
// URL query string param is 0-indexed, $current_page is 1-indexed.
|
||||
$this->assertEqual($destination, '?page=' . $current_page);
|
||||
}
|
||||
if (isset($last)) {
|
||||
$this->assertClass($last, 'pager__item--last', 'Element for last page has .pager__item--last class.');
|
||||
$this->assertTrue($last->a, 'Link to last page found.');
|
||||
$this->assertNoClass($last->a, 'is-active', 'Link to last page is not active.');
|
||||
$destination = $last->a['href'][0]->__toString();
|
||||
// URL query string param is 0-indexed.
|
||||
$this->assertEqual($destination, '?page=' . ($total_pages - 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that an element has a given class.
|
||||
*
|
||||
* @param \SimpleXMLElement $element
|
||||
* The element to test.
|
||||
* @param string $class
|
||||
* The class to assert.
|
||||
* @param string $message
|
||||
* (optional) A verbose message to output.
|
||||
*/
|
||||
protected function assertClass(\SimpleXMLElement $element, $class, $message = NULL) {
|
||||
if (!isset($message)) {
|
||||
$message = "Class .$class found.";
|
||||
}
|
||||
$this->assertTrue(strpos($element['class'], $class) !== FALSE, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that an element does not have a given class.
|
||||
*
|
||||
* @param \SimpleXMLElement $element
|
||||
* The element to test.
|
||||
* @param string $class
|
||||
* The class to assert.
|
||||
* @param string $message
|
||||
* (optional) A verbose message to output.
|
||||
*/
|
||||
protected function assertNoClass(\SimpleXMLElement $element, $class, $message = NULL) {
|
||||
if (!isset($message)) {
|
||||
$message = "Class .$class not found.";
|
||||
}
|
||||
$this->assertTrue(strpos($element['class'], $class) === FALSE, $message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Render;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Functional tests for HtmlResponseAttachmentsProcessor.
|
||||
*
|
||||
* @group Render
|
||||
*/
|
||||
class HtmlResponseAttachmentsTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['render_attached_test'];
|
||||
|
||||
/**
|
||||
* Test rendering of ['#attached'].
|
||||
*/
|
||||
public function testAttachments() {
|
||||
// Test ['#attached']['http_header] = ['Status', $code].
|
||||
$this->drupalGet('/render_attached_test/teapot');
|
||||
$this->assertResponse(418);
|
||||
$this->assertHeader('X-Drupal-Cache', 'MISS');
|
||||
// Repeat for the cache.
|
||||
$this->drupalGet('/render_attached_test/teapot');
|
||||
$this->assertResponse(418);
|
||||
$this->assertHeader('X-Drupal-Cache', 'HIT');
|
||||
|
||||
// Test ['#attached']['http_header'] with various replacement rules.
|
||||
$this->drupalGet('/render_attached_test/header');
|
||||
$this->assertTeapotHeaders();
|
||||
$this->assertHeader('X-Drupal-Cache', 'MISS');
|
||||
// Repeat for the cache.
|
||||
$this->drupalGet('/render_attached_test/header');
|
||||
$this->assertHeader('X-Drupal-Cache', 'HIT');
|
||||
|
||||
// Test ['#attached']['feed'].
|
||||
$this->drupalGet('/render_attached_test/feed');
|
||||
$this->assertHeader('X-Drupal-Cache', 'MISS');
|
||||
$this->assertFeed();
|
||||
// Repeat for the cache.
|
||||
$this->drupalGet('/render_attached_test/feed');
|
||||
$this->assertHeader('X-Drupal-Cache', 'HIT');
|
||||
|
||||
// Test ['#attached']['html_head'].
|
||||
$this->drupalGet('/render_attached_test/head');
|
||||
$this->assertHeader('X-Drupal-Cache', 'MISS');
|
||||
$this->assertHead();
|
||||
// Repeat for the cache.
|
||||
$this->drupalGet('/render_attached_test/head');
|
||||
$this->assertHeader('X-Drupal-Cache', 'HIT');
|
||||
|
||||
// Test ['#attached']['html_head_link'] when outputted as HTTP header.
|
||||
$this->drupalGet('/render_attached_test/html_header_link');
|
||||
$expected_link_headers = [
|
||||
'</foo?bar=<baz>&baz=false>; rel="alternate"',
|
||||
'</foo/bar>; hreflang="nl"; rel="alternate"',
|
||||
];
|
||||
$this->assertEqual($this->drupalGetHeader('link'), implode(',', $expected_link_headers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test caching of ['#attached'].
|
||||
*/
|
||||
public function testRenderCachedBlock() {
|
||||
// Make sure our test block is visible.
|
||||
$this->drupalPlaceBlock('attached_rendering_block', ['region' => 'content']);
|
||||
|
||||
// Get the front page, which should now have our visible block.
|
||||
$this->drupalGet('');
|
||||
// Make sure our block is visible.
|
||||
$this->assertText('Markup from attached_rendering_block.');
|
||||
// Test that all our attached items are present.
|
||||
$this->assertFeed();
|
||||
$this->assertHead();
|
||||
$this->assertResponse(418);
|
||||
$this->assertTeapotHeaders();
|
||||
|
||||
// Reload the page, to test caching.
|
||||
$this->drupalGet('');
|
||||
// Make sure our block is visible.
|
||||
$this->assertText('Markup from attached_rendering_block.');
|
||||
// The header should be present again.
|
||||
$this->assertHeader('X-Test-Teapot', 'Teapot Mode Active');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to make assertions about added HTTP headers.
|
||||
*/
|
||||
protected function assertTeapotHeaders() {
|
||||
$this->assertHeader('X-Test-Teapot', 'Teapot Mode Active');
|
||||
$this->assertHeader('X-Test-Teapot-Replace', 'Teapot replaced');
|
||||
$this->assertHeader('X-Test-Teapot-No-Replace', 'This value is not replaced,This one is added');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to make assertions about the presence of an RSS feed.
|
||||
*/
|
||||
protected function assertFeed() {
|
||||
// Discover the DOM element for the feed link.
|
||||
$test_meta = $this->xpath('//head/link[@href="test://url"]');
|
||||
$this->assertEqual(1, count($test_meta), 'Link has URL.');
|
||||
// Reconcile the other attributes.
|
||||
$test_meta_attributes = [
|
||||
'href' => 'test://url',
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/rss+xml',
|
||||
'title' => 'Your RSS feed.',
|
||||
];
|
||||
$test_meta = reset($test_meta);
|
||||
if (empty($test_meta)) {
|
||||
$this->fail('Unable to find feed link.');
|
||||
}
|
||||
else {
|
||||
foreach ($test_meta->attributes() as $attribute => $value) {
|
||||
$this->assertEqual($value, $test_meta_attributes[$attribute]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to make assertions about HTML head elements.
|
||||
*/
|
||||
protected function assertHead() {
|
||||
// Discover the DOM element for the meta link.
|
||||
$test_meta = $this->xpath('//head/meta[@test-attribute="testvalue"]');
|
||||
$this->assertEqual(1, count($test_meta), 'There\'s only one test attribute.');
|
||||
// Grab the only DOM element.
|
||||
$test_meta = reset($test_meta);
|
||||
if (empty($test_meta)) {
|
||||
$this->fail('Unable to find the head meta.');
|
||||
}
|
||||
else {
|
||||
$test_meta_attributes = $test_meta->attributes();
|
||||
$this->assertEqual($test_meta_attributes['test-attribute'], 'testvalue');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Render;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests that URL bubbleable metadata is correctly bubbled.
|
||||
*
|
||||
* @group Render
|
||||
*/
|
||||
class UrlBubbleableMetadataBubblingTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['cache_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->dumpHeaders = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that URL bubbleable metadata is correctly bubbled.
|
||||
*/
|
||||
public function testUrlBubbleableMetadataBubbling() {
|
||||
// Test that regular URLs bubble up bubbleable metadata when converted to
|
||||
// string.
|
||||
$url = Url::fromRoute('cache_test.url_bubbling');
|
||||
$this->drupalGet($url);
|
||||
$this->assertCacheContext('url.site');
|
||||
$this->assertRaw($url->setAbsolute()->toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Routing;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests for $_GET['destination'] and $_REQUEST['destination'] validation.
|
||||
*
|
||||
* Note: This tests basically the same as
|
||||
* \Drupal\Tests\Core\EventSubscriber\RedirectResponseSubscriberTest::testSanitizeDestinationForGet
|
||||
* \Drupal\Tests\Core\EventSubscriber\RedirectResponseSubscriberTest::testSanitizeDestinationForPost
|
||||
* but we want to be absolutely sure it works.
|
||||
*
|
||||
* @group Routing
|
||||
*/
|
||||
class DestinationTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system_test'];
|
||||
|
||||
/**
|
||||
* Tests that $_GET/$_REQUEST['destination'] only contain internal URLs.
|
||||
*/
|
||||
public function testDestination() {
|
||||
$test_cases = [
|
||||
[
|
||||
'input' => 'node',
|
||||
'output' => 'node',
|
||||
'message' => "Standard internal example node path is present in the 'destination' parameter.",
|
||||
],
|
||||
[
|
||||
'input' => '/example.com',
|
||||
'output' => '/example.com',
|
||||
'message' => 'Internal path with one leading slash is allowed.',
|
||||
],
|
||||
[
|
||||
'input' => '//example.com/test',
|
||||
'output' => '',
|
||||
'message' => 'External URL without scheme is not allowed.',
|
||||
],
|
||||
[
|
||||
'input' => 'example:test',
|
||||
'output' => 'example:test',
|
||||
'message' => 'Internal URL using a colon is allowed.',
|
||||
],
|
||||
[
|
||||
'input' => 'http://example.com',
|
||||
'output' => '',
|
||||
'message' => 'External URL is not allowed.',
|
||||
],
|
||||
[
|
||||
'input' => 'javascript:alert(0)',
|
||||
'output' => 'javascript:alert(0)',
|
||||
'message' => 'Javascript URL is allowed because it is treated as an internal URL.',
|
||||
],
|
||||
];
|
||||
foreach ($test_cases as $test_case) {
|
||||
// Test $_GET['destination'].
|
||||
$this->drupalGet('system-test/get-destination', ['query' => ['destination' => $test_case['input']]]);
|
||||
$this->assertIdentical($test_case['output'], $this->getRawContent(), $test_case['message']);
|
||||
// Test $_REQUEST['destination'].
|
||||
$post_output = $this->drupalPost('system-test/request-destination', '*', ['destination' => $test_case['input']]);
|
||||
$this->assertIdentical($test_case['output'], $post_output, $test_case['message']);
|
||||
}
|
||||
|
||||
// Make sure that 404 pages do not populate $_GET['destination'] with
|
||||
// external URLs.
|
||||
\Drupal::configFactory()->getEditable('system.site')->set('page.404', '/system-test/get-destination')->save();
|
||||
$this->drupalGet('http://example.com', ['external' => FALSE]);
|
||||
$this->assertResponse(404);
|
||||
$this->assertIdentical(Url::fromRoute('<front>')->toString(), $this->getRawContent(), 'External URL is not allowed on 404 pages.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -190,7 +190,7 @@ class SessionHttpsTest extends WebTestBase {
|
||||
}
|
||||
|
||||
// The mock front controllers (http.php and https.php) add the script name
|
||||
// to $_SERVER['REQEUST_URI'] and friends. Therefore it is necessary to
|
||||
// to $_SERVER['REQUEST_URI'] and friends. Therefore it is necessary to
|
||||
// strip that also.
|
||||
$base_url .= 'index.php/';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user