upgrades core to 8.4.2
This commit is contained in:
@@ -5,8 +5,8 @@ package: Core
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @file
|
||||
* Renders BigPipe placeholders using Drupal's Ajax system.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
/**
|
||||
* Executes Ajax commands in <script type="application/vnd.drupal-ajax"> tag.
|
||||
*
|
||||
* These Ajax commands replace placeholders with HTML and load missing CSS/JS.
|
||||
*
|
||||
* @param {number} index
|
||||
* Current index.
|
||||
* @param {HTMLScriptElement} placeholderReplacement
|
||||
* Script tag created by BigPipe.
|
||||
*/
|
||||
function bigPipeProcessPlaceholderReplacement(index, placeholderReplacement) {
|
||||
const placeholderId = placeholderReplacement.getAttribute('data-big-pipe-replacement-for-placeholder-with-id');
|
||||
const content = this.textContent.trim();
|
||||
// Ignore any placeholders that are not in the known placeholder list. Used
|
||||
// to avoid someone trying to XSS the site via the placeholdering mechanism.
|
||||
if (typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined') {
|
||||
// If we try to parse the content too early (when the JSON containing Ajax
|
||||
// commands is still arriving), textContent will be empty which will cause
|
||||
// JSON.parse() to fail. Remove once so that it can be processed again
|
||||
// later.
|
||||
// @see bigPipeProcessDocument()
|
||||
if (content === '') {
|
||||
$(this).removeOnce('big-pipe');
|
||||
}
|
||||
else {
|
||||
const response = JSON.parse(content);
|
||||
// Create a Drupal.Ajax object without associating an element, a
|
||||
// progress indicator or a URL.
|
||||
const ajaxObject = Drupal.ajax({
|
||||
url: '',
|
||||
base: false,
|
||||
element: false,
|
||||
progress: false,
|
||||
});
|
||||
// Then, simulate an AJAX response having arrived, and let the Ajax
|
||||
// system handle it.
|
||||
ajaxObject.success(response, 'success');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a streamed HTML document receiving placeholder replacements.
|
||||
*
|
||||
* @param {HTMLDocument} context
|
||||
* The HTML document containing <script type="application/vnd.drupal-ajax">
|
||||
* tags generated by BigPipe.
|
||||
*
|
||||
* @return {bool}
|
||||
* Returns true when processing has been finished and a stop signal has been
|
||||
* found.
|
||||
*/
|
||||
function bigPipeProcessDocument(context) {
|
||||
// Make sure we have BigPipe-related scripts before processing further.
|
||||
if (!context.querySelector('script[data-big-pipe-event="start"]')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$(context).find('script[data-big-pipe-replacement-for-placeholder-with-id]')
|
||||
.once('big-pipe')
|
||||
.each(bigPipeProcessPlaceholderReplacement);
|
||||
|
||||
// If we see the stop signal, clear the timeout: all placeholder
|
||||
// replacements are guaranteed to be received and processed.
|
||||
if (context.querySelector('script[data-big-pipe-event="stop"]')) {
|
||||
if (timeoutID) {
|
||||
clearTimeout(timeoutID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function bigPipeProcess() {
|
||||
timeoutID = setTimeout(() => {
|
||||
if (!bigPipeProcessDocument(document)) {
|
||||
bigPipeProcess();
|
||||
}
|
||||
}, interval);
|
||||
}
|
||||
|
||||
// The frequency with which to check for newly arrived BigPipe placeholders.
|
||||
// Hence 50 ms means we check 20 times per second. Setting this to 100 ms or
|
||||
// more would cause the user to see content appear noticeably slower.
|
||||
var interval = drupalSettings.bigPipeInterval || 50;
|
||||
// The internal ID to contain the watcher service.
|
||||
let timeoutID;
|
||||
|
||||
bigPipeProcess();
|
||||
|
||||
// If something goes wrong, make sure everything is cleaned up and has had a
|
||||
// chance to be processed with everything loaded.
|
||||
$(window).on('load', () => {
|
||||
if (timeoutID) {
|
||||
clearTimeout(timeoutID);
|
||||
}
|
||||
bigPipeProcessDocument(document);
|
||||
});
|
||||
}(jQuery, Drupal, drupalSettings));
|
||||
@@ -1,76 +1,40 @@
|
||||
/**
|
||||
* @file
|
||||
* Renders BigPipe placeholders using Drupal's Ajax system.
|
||||
*/
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Executes Ajax commands in <script type="application/vnd.drupal-ajax"> tag.
|
||||
*
|
||||
* These Ajax commands replace placeholders with HTML and load missing CSS/JS.
|
||||
*
|
||||
* @param {number} index
|
||||
* Current index.
|
||||
* @param {HTMLScriptElement} placeholderReplacement
|
||||
* Script tag created by BigPipe.
|
||||
*/
|
||||
function bigPipeProcessPlaceholderReplacement(index, placeholderReplacement) {
|
||||
var placeholderId = placeholderReplacement.getAttribute('data-big-pipe-replacement-for-placeholder-with-id');
|
||||
var content = this.textContent.trim();
|
||||
// Ignore any placeholders that are not in the known placeholder list. Used
|
||||
// to avoid someone trying to XSS the site via the placeholdering mechanism.
|
||||
|
||||
if (typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined') {
|
||||
// If we try to parse the content too early (when the JSON containing Ajax
|
||||
// commands is still arriving), textContent will be empty which will cause
|
||||
// JSON.parse() to fail. Remove once so that it can be processed again
|
||||
// later.
|
||||
// @see bigPipeProcessDocument()
|
||||
if (content === '') {
|
||||
$(this).removeOnce('big-pipe');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
var response = JSON.parse(content);
|
||||
// Create a Drupal.Ajax object without associating an element, a
|
||||
// progress indicator or a URL.
|
||||
|
||||
var ajaxObject = Drupal.ajax({
|
||||
url: '',
|
||||
base: false,
|
||||
element: false,
|
||||
progress: false
|
||||
});
|
||||
// Then, simulate an AJAX response having arrived, and let the Ajax
|
||||
// system handle it.
|
||||
|
||||
ajaxObject.success(response, 'success');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a streamed HTML document receiving placeholder replacements.
|
||||
*
|
||||
* @param {HTMLDocument} context
|
||||
* The HTML document containing <script type="application/vnd.drupal-ajax">
|
||||
* tags generated by BigPipe.
|
||||
*
|
||||
* @return {bool}
|
||||
* Returns true when processing has been finished and a stop signal has been
|
||||
* found.
|
||||
*/
|
||||
function bigPipeProcessDocument(context) {
|
||||
// Make sure we have BigPipe-related scripts before processing further.
|
||||
if (!context.querySelector('script[data-big-pipe-event="start"]')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$(context).find('script[data-big-pipe-replacement-for-placeholder-with-id]')
|
||||
.once('big-pipe')
|
||||
.each(bigPipeProcessPlaceholderReplacement);
|
||||
$(context).find('script[data-big-pipe-replacement-for-placeholder-with-id]').once('big-pipe').each(bigPipeProcessPlaceholderReplacement);
|
||||
|
||||
// If we see the stop signal, clear the timeout: all placeholder
|
||||
// replacements are guaranteed to be received and processed.
|
||||
if (context.querySelector('script[data-big-pipe-event="stop"]')) {
|
||||
if (timeoutID) {
|
||||
clearTimeout(timeoutID);
|
||||
@@ -89,22 +53,16 @@
|
||||
}, interval);
|
||||
}
|
||||
|
||||
// The frequency with which to check for newly arrived BigPipe placeholders.
|
||||
// Hence 50 ms means we check 20 times per second. Setting this to 100 ms or
|
||||
// more would cause the user to see content appear noticeably slower.
|
||||
var interval = drupalSettings.bigPipeInterval || 50;
|
||||
// The internal ID to contain the watcher service.
|
||||
var timeoutID;
|
||||
|
||||
var timeoutID = void 0;
|
||||
|
||||
bigPipeProcess();
|
||||
|
||||
// If something goes wrong, make sure everything is cleaned up and has had a
|
||||
// chance to be processed with everything loaded.
|
||||
$(window).on('load', function () {
|
||||
if (timeoutID) {
|
||||
clearTimeout(timeoutID);
|
||||
}
|
||||
bigPipeProcessDocument(document);
|
||||
});
|
||||
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
@@ -109,7 +109,7 @@ class BigPipeStrategy implements PlaceholderStrategyInterface {
|
||||
$request = $this->requestStack->getCurrentRequest();
|
||||
|
||||
// @todo remove this check when https://www.drupal.org/node/2367555 lands.
|
||||
if (!$request->isMethodSafe()) {
|
||||
if (!$request->isMethodCacheable()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+412
@@ -0,0 +1,412 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
namespace Drupal\big_pipe_test;
|
||||
|
||||
use Drupal\big_pipe\Render\BigPipeMarkup;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* BigPipe placeholder test cases for use in both unit and integration tests.
|
||||
*
|
||||
* - Unit test:
|
||||
* \Drupal\Tests\big_pipe\Unit\Render\Placeholder\BigPipeStrategyTest
|
||||
* - Integration test for BigPipe with JS on:
|
||||
* \Drupal\Tests\big_pipe\Functional\BigPipeTest::testBigPipe()
|
||||
* - Integration test for BigPipe with JS off:
|
||||
* \Drupal\Tests\big_pipe\Functional\BigPipeTest::testBigPipeNoJs()
|
||||
*/
|
||||
class BigPipePlaceholderTestCases {
|
||||
|
||||
/**
|
||||
* Gets all BigPipe placeholder test cases.
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface|null $container
|
||||
* Optional. Necessary to get the embedded AJAX/HTML responses.
|
||||
* @param \Drupal\Core\Session\AccountInterface|null $user
|
||||
* Optional. Necessary to get the embedded AJAX/HTML responses.
|
||||
*
|
||||
* @return \Drupal\big_pipe_test\BigPipePlaceholderTestCase[]
|
||||
*/
|
||||
public static function cases(ContainerInterface $container = NULL, AccountInterface $user = NULL) {
|
||||
// Define the two types of cacheability that we expect to see. These will be
|
||||
// used in the expectations.
|
||||
$cacheability_depends_on_session_only = [
|
||||
'max-age' => 0,
|
||||
'contexts' => ['session.exists'],
|
||||
];
|
||||
$cacheability_depends_on_session_and_nojs_cookie = [
|
||||
'max-age' => 0,
|
||||
'contexts' => ['session.exists', 'cookies:big_pipe_nojs'],
|
||||
];
|
||||
|
||||
|
||||
// 1. Real-world example of HTML placeholder.
|
||||
$status_messages = new BigPipePlaceholderTestCase(
|
||||
['#type' => 'status_messages'],
|
||||
'<drupal-render-placeholder callback="Drupal\Core\Render\Element\StatusMessages::renderMessages" arguments="0" token="_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></drupal-render-placeholder>',
|
||||
[
|
||||
'#lazy_builder' => [
|
||||
'Drupal\Core\Render\Element\StatusMessages::renderMessages',
|
||||
[NULL]
|
||||
],
|
||||
]
|
||||
);
|
||||
$status_messages->bigPipePlaceholderId = 'callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA';
|
||||
$status_messages->bigPipePlaceholderRenderArray = [
|
||||
'#markup' => '<span data-big-pipe-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></span>',
|
||||
'#cache' => $cacheability_depends_on_session_and_nojs_cookie,
|
||||
'#attached' => [
|
||||
'library' => ['big_pipe/big_pipe'],
|
||||
'drupalSettings' => [
|
||||
'bigPipePlaceholderIds' => [
|
||||
'callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA' => TRUE,
|
||||
],
|
||||
],
|
||||
'big_pipe_placeholders' => [
|
||||
'callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA' => $status_messages->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$status_messages->bigPipeNoJsPlaceholder = '<span data-big-pipe-nojs-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></span>';
|
||||
$status_messages->bigPipeNoJsPlaceholderRenderArray = [
|
||||
'#markup' => '<span data-big-pipe-nojs-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></span>',
|
||||
'#cache' => $cacheability_depends_on_session_and_nojs_cookie,
|
||||
'#attached' => [
|
||||
'big_pipe_nojs_placeholders' => [
|
||||
'<span data-big-pipe-nojs-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></span>' => $status_messages->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
if ($container && $user) {
|
||||
$status_messages->embeddedAjaxResponseCommands = [
|
||||
[
|
||||
'command' => 'insert',
|
||||
'method' => 'replaceWith',
|
||||
'selector' => '[data-big-pipe-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"]',
|
||||
'data' => ' <div role="contentinfo" aria-label="Status message" class="messages messages--status">' . "\n" . ' <h2 class="visually-hidden">Status message</h2>' . "\n" . ' Hello from BigPipe!' . "\n" . ' </div>' . "\n ",
|
||||
'settings' => NULL,
|
||||
],
|
||||
];
|
||||
$status_messages->embeddedHtmlResponse = '<div role="contentinfo" aria-label="Status message" class="messages messages--status">' . "\n" . ' <h2 class="visually-hidden">Status message</h2>' . "\n" . ' Hello from BigPipe!' . "\n" . ' </div>' . "\n \n";
|
||||
}
|
||||
|
||||
|
||||
// 2. Real-world example of HTML attribute value placeholder: form action.
|
||||
$form_action = new BigPipePlaceholderTestCase(
|
||||
$container ? $container->get('form_builder')->getForm('Drupal\big_pipe_test\Form\BigPipeTestForm') : [],
|
||||
'form_action_cc611e1d',
|
||||
[
|
||||
'#lazy_builder' => ['form_builder:renderPlaceholderFormAction', []],
|
||||
]
|
||||
);
|
||||
$form_action->bigPipeNoJsPlaceholder = 'big_pipe_nojs_placeholder_attribute_safe:form_action_cc611e1d';
|
||||
$form_action->bigPipeNoJsPlaceholderRenderArray = [
|
||||
'#markup' => 'big_pipe_nojs_placeholder_attribute_safe:form_action_cc611e1d',
|
||||
'#cache' => $cacheability_depends_on_session_only,
|
||||
'#attached' => [
|
||||
'big_pipe_nojs_placeholders' => [
|
||||
'big_pipe_nojs_placeholder_attribute_safe:form_action_cc611e1d' => $form_action->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
if ($container) {
|
||||
$form_action->embeddedHtmlResponse = '<form class="big-pipe-test-form" data-drupal-selector="big-pipe-test-form" action="' . base_path() . 'big_pipe_test"';
|
||||
}
|
||||
|
||||
|
||||
// 3. Real-world example of HTML attribute value subset placeholder: CSRF
|
||||
// token in link.
|
||||
$csrf_token = new BigPipePlaceholderTestCase(
|
||||
[
|
||||
'#title' => 'Link with CSRF token',
|
||||
'#type' => 'link',
|
||||
'#url' => Url::fromRoute('system.theme_set_default'),
|
||||
],
|
||||
'e88b559cce72c80b687d56b0e2a3a5ae4b66bc0e',
|
||||
[
|
||||
'#lazy_builder' => [
|
||||
'route_processor_csrf:renderPlaceholderCsrfToken',
|
||||
['admin/config/user-interface/shortcut/manage/default/add-link-inline']
|
||||
],
|
||||
]
|
||||
);
|
||||
$csrf_token->bigPipeNoJsPlaceholder = 'big_pipe_nojs_placeholder_attribute_safe:e88b559cce72c80b687d56b0e2a3a5ae4b66bc0e';
|
||||
$csrf_token->bigPipeNoJsPlaceholderRenderArray = [
|
||||
'#markup' => 'big_pipe_nojs_placeholder_attribute_safe:e88b559cce72c80b687d56b0e2a3a5ae4b66bc0e',
|
||||
'#cache' => $cacheability_depends_on_session_only,
|
||||
'#attached' => [
|
||||
'big_pipe_nojs_placeholders' => [
|
||||
'big_pipe_nojs_placeholder_attribute_safe:e88b559cce72c80b687d56b0e2a3a5ae4b66bc0e' => $csrf_token->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
if ($container) {
|
||||
$csrf_token->embeddedHtmlResponse = $container->get('csrf_token')->get('admin/appearance/default');
|
||||
}
|
||||
|
||||
|
||||
// 4. Edge case: custom string to be considered as a placeholder that
|
||||
// happens to not be valid HTML.
|
||||
$hello = new BigPipePlaceholderTestCase(
|
||||
[
|
||||
'#markup' => BigPipeMarkup::create('<hello'),
|
||||
'#attached' => [
|
||||
'placeholders' => [
|
||||
'<hello' => ['#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::helloOrYarhar', []]],
|
||||
]
|
||||
],
|
||||
],
|
||||
'<hello',
|
||||
[
|
||||
'#lazy_builder' => [
|
||||
'hello_or_yarhar',
|
||||
[]
|
||||
],
|
||||
]
|
||||
);
|
||||
$hello->bigPipeNoJsPlaceholder = 'big_pipe_nojs_placeholder_attribute_safe:<hello';
|
||||
$hello->bigPipeNoJsPlaceholderRenderArray = [
|
||||
'#markup' => 'big_pipe_nojs_placeholder_attribute_safe:<hello',
|
||||
'#cache' => $cacheability_depends_on_session_only,
|
||||
'#attached' => [
|
||||
'big_pipe_nojs_placeholders' => [
|
||||
'big_pipe_nojs_placeholder_attribute_safe:<hello' => $hello->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$hello->embeddedHtmlResponse = '<marquee>Yarhar llamas forever!</marquee>';
|
||||
|
||||
|
||||
// 5. Edge case: non-#lazy_builder placeholder.
|
||||
$current_time = new BigPipePlaceholderTestCase(
|
||||
[
|
||||
'#markup' => BigPipeMarkup::create('<time>CURRENT TIME</time>'),
|
||||
'#attached' => [
|
||||
'placeholders' => [
|
||||
'<time>CURRENT TIME</time>' => [
|
||||
'#pre_render' => [
|
||||
'\Drupal\big_pipe_test\BigPipeTestController::currentTime',
|
||||
],
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'<time>CURRENT TIME</time>',
|
||||
[
|
||||
'#pre_render' => ['current_time'],
|
||||
]
|
||||
);
|
||||
$current_time->bigPipePlaceholderId = 'timecurrent-timetime';
|
||||
$current_time->bigPipePlaceholderRenderArray = [
|
||||
'#markup' => '<span data-big-pipe-placeholder-id="timecurrent-timetime"></span>',
|
||||
'#cache' => $cacheability_depends_on_session_and_nojs_cookie,
|
||||
'#attached' => [
|
||||
'library' => ['big_pipe/big_pipe'],
|
||||
'drupalSettings' => [
|
||||
'bigPipePlaceholderIds' => [
|
||||
'timecurrent-timetime' => TRUE,
|
||||
],
|
||||
],
|
||||
'big_pipe_placeholders' => [
|
||||
'timecurrent-timetime' => $current_time->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$current_time->embeddedAjaxResponseCommands = [
|
||||
[
|
||||
'command' => 'insert',
|
||||
'method' => 'replaceWith',
|
||||
'selector' => '[data-big-pipe-placeholder-id="timecurrent-timetime"]',
|
||||
'data' => '<time datetime="1991-03-14"></time>',
|
||||
'settings' => NULL,
|
||||
],
|
||||
];
|
||||
$current_time->bigPipeNoJsPlaceholder = '<span data-big-pipe-nojs-placeholder-id="timecurrent-timetime"></span>';
|
||||
$current_time->bigPipeNoJsPlaceholderRenderArray = [
|
||||
'#markup' => '<span data-big-pipe-nojs-placeholder-id="timecurrent-timetime"></span>',
|
||||
'#cache' => $cacheability_depends_on_session_and_nojs_cookie,
|
||||
'#attached' => [
|
||||
'big_pipe_nojs_placeholders' => [
|
||||
'<span data-big-pipe-nojs-placeholder-id="timecurrent-timetime"></span>' => $current_time->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$current_time->embeddedHtmlResponse = '<time datetime="1991-03-14"></time>';
|
||||
|
||||
|
||||
// 6. Edge case: #lazy_builder that throws an exception.
|
||||
$exception = new BigPipePlaceholderTestCase(
|
||||
[
|
||||
'#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::exception', ['llamas', 'suck']],
|
||||
'#create_placeholder' => TRUE,
|
||||
],
|
||||
'<drupal-render-placeholder callback="\Drupal\big_pipe_test\BigPipeTestController::exception" arguments="0=llamas&1=suck" token="uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU"></drupal-render-placeholder>',
|
||||
[
|
||||
'#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::exception', ['llamas', 'suck']],
|
||||
]
|
||||
);
|
||||
$exception->bigPipePlaceholderId = 'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args%5B0%5D=llamas&args%5B1%5D=suck&token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU';
|
||||
$exception->bigPipePlaceholderRenderArray = [
|
||||
'#markup' => '<span data-big-pipe-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args%5B0%5D=llamas&args%5B1%5D=suck&token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU"></span>',
|
||||
'#cache' => $cacheability_depends_on_session_and_nojs_cookie,
|
||||
'#attached' => [
|
||||
'library' => ['big_pipe/big_pipe'],
|
||||
'drupalSettings' => [
|
||||
'bigPipePlaceholderIds' => [
|
||||
'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args%5B0%5D=llamas&args%5B1%5D=suck&token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU' => TRUE,
|
||||
],
|
||||
],
|
||||
'big_pipe_placeholders' => [
|
||||
'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args%5B0%5D=llamas&args%5B1%5D=suck&token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU' => $exception->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$exception->embeddedAjaxResponseCommands = NULL;
|
||||
$exception->bigPipeNoJsPlaceholder = '<span data-big-pipe-nojs-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args%5B0%5D=llamas&args%5B1%5D=suck&token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU"></span>';
|
||||
$exception->bigPipeNoJsPlaceholderRenderArray = [
|
||||
'#markup' => $exception->bigPipeNoJsPlaceholder,
|
||||
'#cache' => $cacheability_depends_on_session_and_nojs_cookie,
|
||||
'#attached' => [
|
||||
'big_pipe_nojs_placeholders' => [
|
||||
$exception->bigPipeNoJsPlaceholder => $exception->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$exception->embeddedHtmlResponse = NULL;
|
||||
|
||||
// 7. Edge case: response filter throwing an exception for this placeholder.
|
||||
$embedded_response_exception = new BigPipePlaceholderTestCase(
|
||||
[
|
||||
'#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::responseException', []],
|
||||
'#create_placeholder' => TRUE,
|
||||
],
|
||||
'<drupal-render-placeholder callback="\Drupal\big_pipe_test\BigPipeTestController::responseException" arguments="" token="PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU"></drupal-render-placeholder>',
|
||||
[
|
||||
'#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::responseException', []],
|
||||
]
|
||||
);
|
||||
$embedded_response_exception->bigPipePlaceholderId = 'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU';
|
||||
$embedded_response_exception->bigPipePlaceholderRenderArray = [
|
||||
'#markup' => '<span data-big-pipe-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU"></span>',
|
||||
'#cache' => $cacheability_depends_on_session_and_nojs_cookie,
|
||||
'#attached' => [
|
||||
'library' => ['big_pipe/big_pipe'],
|
||||
'drupalSettings' => [
|
||||
'bigPipePlaceholderIds' => [
|
||||
'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU' => TRUE,
|
||||
],
|
||||
],
|
||||
'big_pipe_placeholders' => [
|
||||
'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU' => $embedded_response_exception->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$embedded_response_exception->embeddedAjaxResponseCommands = NULL;
|
||||
$embedded_response_exception->bigPipeNoJsPlaceholder = '<span data-big-pipe-nojs-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU"></span>';
|
||||
$embedded_response_exception->bigPipeNoJsPlaceholderRenderArray = [
|
||||
'#markup' => $embedded_response_exception->bigPipeNoJsPlaceholder,
|
||||
'#cache' => $cacheability_depends_on_session_and_nojs_cookie,
|
||||
'#attached' => [
|
||||
'big_pipe_nojs_placeholders' => [
|
||||
$embedded_response_exception->bigPipeNoJsPlaceholder => $embedded_response_exception->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$exception->embeddedHtmlResponse = NULL;
|
||||
|
||||
return [
|
||||
'html' => $status_messages,
|
||||
'html_attribute_value' => $form_action,
|
||||
'html_attribute_value_subset' => $csrf_token,
|
||||
'edge_case__invalid_html' => $hello,
|
||||
'edge_case__html_non_lazy_builder' => $current_time,
|
||||
'exception__lazy_builder' => $exception,
|
||||
'exception__embedded_response' => $embedded_response_exception,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BigPipePlaceholderTestCase {
|
||||
|
||||
/**
|
||||
* The original render array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $renderArray;
|
||||
|
||||
/**
|
||||
* The expected corresponding placeholder string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $placeholder;
|
||||
|
||||
/**
|
||||
* The expected corresponding placeholder render array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $placeholderRenderArray;
|
||||
|
||||
/**
|
||||
* The expected BigPipe placeholder ID.
|
||||
*
|
||||
* (Only possible for HTML placeholders.)
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
public $bigPipePlaceholderId = NULL;
|
||||
|
||||
/**
|
||||
* The corresponding expected BigPipe placeholder render array.
|
||||
*
|
||||
* @var null|array
|
||||
*/
|
||||
public $bigPipePlaceholderRenderArray = NULL;
|
||||
|
||||
/**
|
||||
* The corresponding expected embedded AJAX response.
|
||||
*
|
||||
* @var null|array
|
||||
*/
|
||||
public $embeddedAjaxResponseCommands = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* The expected BigPipe no-JS placeholder.
|
||||
*
|
||||
* (Possible for all placeholders, HTML or non-HTML.)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $bigPipeNoJsPlaceholder;
|
||||
|
||||
/**
|
||||
* The corresponding expected BigPipe no-JS placeholder render array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $bigPipeNoJsPlaceholderRenderArray;
|
||||
|
||||
/**
|
||||
* The corresponding expected embedded HTML response.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $embeddedHtmlResponse;
|
||||
|
||||
public function __construct(array $render_array, $placeholder, array $placeholder_render_array) {
|
||||
$this->renderArray = $render_array;
|
||||
$this->placeholder = $placeholder;
|
||||
$this->placeholderRenderArray = $placeholder_render_array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Drupal\big_pipe_test;
|
||||
|
||||
use Drupal\big_pipe\Render\BigPipeMarkup;
|
||||
use Drupal\big_pipe\Tests\BigPipePlaceholderTestCases;
|
||||
use Drupal\big_pipe_test\EventSubscriber\BigPipeTestSubscriber;
|
||||
|
||||
class BigPipeTestController {
|
||||
@@ -61,7 +60,7 @@ class BigPipeTestController {
|
||||
/**
|
||||
* A page with multiple occurrences of the same placeholder.
|
||||
*
|
||||
* @see \Drupal\big_pipe\Tests\BigPipeTest::testBigPipeMultipleOccurrencePlaceholders()
|
||||
* @see \Drupal\Tests\big_pipe\Functional\BigPipeTest::testBigPipeMultiOccurrencePlaceholders()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -134,7 +133,7 @@ class BigPipeTestController {
|
||||
/**
|
||||
* #lazy_builder callback; returns the current count.
|
||||
*
|
||||
* @see \Drupal\big_pipe\Tests\BigPipeTest::testBigPipeMultipleOccurrencePlaceholders()
|
||||
* @see \Drupal\Tests\big_pipe\Functional\BigPipeTest::testBigPipeMultiOccurrencePlaceholders()
|
||||
*
|
||||
* @return array
|
||||
* The render array.
|
||||
|
||||
@@ -35,6 +35,6 @@ class BigPipeTestForm extends FormBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) { }
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,486 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\big_pipe\Functional;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
|
||||
use Drupal\big_pipe\Render\BigPipe;
|
||||
use Drupal\big_pipe_test\BigPipePlaceholderTestCases;
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Logger\RfcLogLevel;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests BigPipe's no-JS detection & response delivery (with and without JS).
|
||||
*
|
||||
* Covers:
|
||||
* - big_pipe_page_attachments()
|
||||
* - \Drupal\big_pipe\Controller\BigPipeController
|
||||
* - \Drupal\big_pipe\EventSubscriber\HtmlResponseBigPipeSubscriber
|
||||
* - \Drupal\big_pipe\Render\BigPipe
|
||||
*
|
||||
* @group big_pipe
|
||||
*/
|
||||
class BigPipeTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['big_pipe', 'big_pipe_test', 'dblog'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $dumpHeaders = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Ignore the <meta> refresh that big_pipe.module sets. It causes a redirect
|
||||
// to a page that sets another cookie, which causes WebTestBase to lose the
|
||||
// session cookie. To avoid this problem, tests should first call
|
||||
// drupalGet() and then call checkForMetaRefresh() manually, and then reset
|
||||
// $this->maximumMetaRefreshCount and $this->metaRefreshCount.
|
||||
// @see doMetaRefresh()
|
||||
$this->maximumMetaRefreshCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a single <meta> refresh explicitly.
|
||||
*
|
||||
* This test disables the automatic <meta> refresh checking, each time it is
|
||||
* desired that this runs, a test case must explicitly call this.
|
||||
*
|
||||
* @see setUp()
|
||||
*/
|
||||
protected function performMetaRefresh() {
|
||||
$this->maximumMetaRefreshCount = 1;
|
||||
$this->checkForMetaRefresh();
|
||||
$this->maximumMetaRefreshCount = 0;
|
||||
$this->metaRefreshCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests BigPipe's no-JS detection.
|
||||
*
|
||||
* Covers:
|
||||
* - big_pipe_page_attachments()
|
||||
* - \Drupal\big_pipe\Controller\BigPipeController
|
||||
*/
|
||||
public function testNoJsDetection() {
|
||||
$no_js_to_js_markup = '<script>document.cookie = "' . BigPipeStrategy::NOJS_COOKIE . '=1; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"</script>';
|
||||
|
||||
// 1. No session (anonymous).
|
||||
$this->drupalGet(Url::fromRoute('<front>'));
|
||||
$this->assertSessionCookieExists(FALSE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
|
||||
$this->assertNoRaw($no_js_to_js_markup);
|
||||
|
||||
// 2. Session (authenticated).
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->assertSessionCookieExists(TRUE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
$this->assertRaw('<noscript><meta http-equiv="Refresh" content="0; URL=' . base_path() . 'big_pipe/no-js?destination=' . base_path() . 'user/1" />' . "\n" . '</noscript>');
|
||||
$this->assertNoRaw($no_js_to_js_markup);
|
||||
$this->assertBigPipeNoJsMetaRefreshRedirect();
|
||||
$this->assertBigPipeNoJsCookieExists(TRUE);
|
||||
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
|
||||
$this->assertRaw($no_js_to_js_markup);
|
||||
$this->drupalLogout();
|
||||
|
||||
// Close the prior connection and remove the collected state.
|
||||
$this->getSession()->reset();
|
||||
|
||||
// 3. Session (anonymous).
|
||||
$this->drupalGet(Url::fromRoute('user.login', [], ['query' => ['trigger_session' => 1]]));
|
||||
$this->drupalGet(Url::fromRoute('user.login'));
|
||||
$this->assertSessionCookieExists(TRUE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
$this->assertRaw('<noscript><meta http-equiv="Refresh" content="0; URL=' . base_path() . 'big_pipe/no-js?destination=' . base_path() . 'user/login" />' . "\n" . '</noscript>');
|
||||
$this->assertNoRaw($no_js_to_js_markup);
|
||||
$this->assertBigPipeNoJsMetaRefreshRedirect();
|
||||
$this->assertBigPipeNoJsCookieExists(TRUE);
|
||||
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
|
||||
$this->assertRaw($no_js_to_js_markup);
|
||||
|
||||
// Close the prior connection and remove the collected state.
|
||||
$this->getSession()->reset();
|
||||
|
||||
// Edge case: route with '_no_big_pipe' option.
|
||||
$this->drupalGet(Url::fromRoute('no_big_pipe'));
|
||||
$this->assertSessionCookieExists(FALSE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
|
||||
$this->assertNoRaw($no_js_to_js_markup);
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->drupalGet(Url::fromRoute('no_big_pipe'));
|
||||
$this->assertSessionCookieExists(TRUE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
|
||||
$this->assertNoRaw($no_js_to_js_markup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests BigPipe-delivered HTML responses when JavaScript is enabled.
|
||||
*
|
||||
* Covers:
|
||||
* - \Drupal\big_pipe\EventSubscriber\HtmlResponseBigPipeSubscriber
|
||||
* - \Drupal\big_pipe\Render\BigPipe
|
||||
* - \Drupal\big_pipe\Render\BigPipe::sendPlaceholders()
|
||||
*
|
||||
* @see \Drupal\big_pipe_test\BigPipePlaceholderTestCases
|
||||
*/
|
||||
public function testBigPipe() {
|
||||
// Simulate production.
|
||||
$this->config('system.logging')->set('error_level', ERROR_REPORTING_HIDE)->save();
|
||||
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->assertSessionCookieExists(TRUE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
|
||||
$log_count = db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField();
|
||||
|
||||
// By not calling performMetaRefresh() here, we simulate JavaScript being
|
||||
// enabled, because as far as the BigPipe module is concerned, JavaScript is
|
||||
// enabled in the browser as long as the BigPipe no-JS cookie is *not* set.
|
||||
// @see setUp()
|
||||
// @see performMetaRefresh()
|
||||
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test'));
|
||||
$this->assertBigPipeResponseHeadersPresent();
|
||||
$this->assertNoCacheTag('cache_tag_set_in_lazy_builder');
|
||||
|
||||
$this->setCsrfTokenSeedInTestEnvironment();
|
||||
$cases = $this->getTestCases();
|
||||
$this->assertBigPipeNoJsPlaceholders([
|
||||
$cases['edge_case__invalid_html']->bigPipeNoJsPlaceholder => $cases['edge_case__invalid_html']->embeddedHtmlResponse,
|
||||
$cases['html_attribute_value']->bigPipeNoJsPlaceholder => $cases['html_attribute_value']->embeddedHtmlResponse,
|
||||
$cases['html_attribute_value_subset']->bigPipeNoJsPlaceholder => $cases['html_attribute_value_subset']->embeddedHtmlResponse,
|
||||
]);
|
||||
$this->assertBigPipePlaceholders([
|
||||
$cases['html']->bigPipePlaceholderId => Json::encode($cases['html']->embeddedAjaxResponseCommands),
|
||||
$cases['edge_case__html_non_lazy_builder']->bigPipePlaceholderId => Json::encode($cases['edge_case__html_non_lazy_builder']->embeddedAjaxResponseCommands),
|
||||
$cases['exception__lazy_builder']->bigPipePlaceholderId => NULL,
|
||||
$cases['exception__embedded_response']->bigPipePlaceholderId => NULL,
|
||||
], [
|
||||
0 => $cases['edge_case__html_non_lazy_builder']->bigPipePlaceholderId,
|
||||
// The 'html' case contains the 'status messages' placeholder, which is
|
||||
// always rendered last.
|
||||
1 => $cases['html']->bigPipePlaceholderId,
|
||||
]);
|
||||
|
||||
$this->assertRaw('</body>', 'Closing body tag present.');
|
||||
|
||||
$this->pass('Verifying BigPipe assets are present…', 'Debug');
|
||||
$this->assertFalse(empty($this->getDrupalSettings()), 'drupalSettings present.');
|
||||
$this->assertTrue(in_array('big_pipe/big_pipe', explode(',', $this->getDrupalSettings()['ajaxPageState']['libraries'])), 'BigPipe asset library is present.');
|
||||
|
||||
// Verify that the two expected exceptions are logged as errors.
|
||||
$this->assertEqual($log_count + 2, db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField(), 'Two new watchdog entries.');
|
||||
$records = db_query('SELECT * FROM {watchdog} ORDER BY wid DESC LIMIT 2')->fetchAll();
|
||||
$this->assertEqual(RfcLogLevel::ERROR, $records[0]->severity);
|
||||
$this->assertTrue(FALSE !== strpos((string) unserialize($records[0]->variables)['@message'], 'Oh noes!'));
|
||||
$this->assertEqual(RfcLogLevel::ERROR, $records[1]->severity);
|
||||
$this->assertTrue(FALSE !== strpos((string) unserialize($records[1]->variables)['@message'], 'You are not allowed to say llamas are not cool!'));
|
||||
|
||||
// Verify that 4xx responses work fine. (4xx responses are handled by
|
||||
// subrequests to a route pointing to a controller with the desired output.)
|
||||
$this->drupalGet(Url::fromUri('base:non-existing-path'));
|
||||
|
||||
// Simulate development.
|
||||
$this->pass('Verifying BigPipe provides useful error output when an error occurs while rendering a placeholder if verbose error logging is enabled.', 'Debug');
|
||||
$this->config('system.logging')->set('error_level', ERROR_REPORTING_DISPLAY_VERBOSE)->save();
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test'));
|
||||
// The 'edge_case__html_exception' case throws an exception.
|
||||
$this->assertRaw('The website encountered an unexpected error. Please try again later');
|
||||
$this->assertRaw('You are not allowed to say llamas are not cool!');
|
||||
$this->assertNoRaw(BigPipe::STOP_SIGNAL, 'BigPipe stop signal absent: error occurred before then.');
|
||||
$this->assertNoRaw('</body>', 'Closing body tag absent: error occurred before then.');
|
||||
// The exception is expected. Do not interpret it as a test failure.
|
||||
unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests BigPipe-delivered HTML responses when JavaScript is disabled.
|
||||
*
|
||||
* Covers:
|
||||
* - \Drupal\big_pipe\EventSubscriber\HtmlResponseBigPipeSubscriber
|
||||
* - \Drupal\big_pipe\Render\BigPipe
|
||||
* - \Drupal\big_pipe\Render\BigPipe::sendNoJsPlaceholders()
|
||||
*
|
||||
* @see \Drupal\big_pipe_test\BigPipePlaceholderTestCases
|
||||
*/
|
||||
public function testBigPipeNoJs() {
|
||||
// Simulate production.
|
||||
$this->config('system.logging')->set('error_level', ERROR_REPORTING_HIDE)->save();
|
||||
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->assertSessionCookieExists(TRUE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
|
||||
// By calling performMetaRefresh() here, we simulate JavaScript being
|
||||
// disabled, because as far as the BigPipe module is concerned, it is
|
||||
// enabled in the browser when the BigPipe no-JS cookie is set.
|
||||
// @see setUp()
|
||||
// @see performMetaRefresh()
|
||||
$this->performMetaRefresh();
|
||||
$this->assertBigPipeNoJsCookieExists(TRUE);
|
||||
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test'));
|
||||
$this->assertBigPipeResponseHeadersPresent();
|
||||
$this->assertNoCacheTag('cache_tag_set_in_lazy_builder');
|
||||
|
||||
$this->setCsrfTokenSeedInTestEnvironment();
|
||||
$cases = $this->getTestCases();
|
||||
$this->assertBigPipeNoJsPlaceholders([
|
||||
$cases['edge_case__invalid_html']->bigPipeNoJsPlaceholder => $cases['edge_case__invalid_html']->embeddedHtmlResponse,
|
||||
$cases['html_attribute_value']->bigPipeNoJsPlaceholder => $cases['html_attribute_value']->embeddedHtmlResponse,
|
||||
$cases['html_attribute_value_subset']->bigPipeNoJsPlaceholder => $cases['html_attribute_value_subset']->embeddedHtmlResponse,
|
||||
$cases['html']->bigPipeNoJsPlaceholder => $cases['html']->embeddedHtmlResponse,
|
||||
$cases['edge_case__html_non_lazy_builder']->bigPipeNoJsPlaceholder => $cases['edge_case__html_non_lazy_builder']->embeddedHtmlResponse,
|
||||
$cases['exception__lazy_builder']->bigPipePlaceholderId => NULL,
|
||||
$cases['exception__embedded_response']->bigPipePlaceholderId => NULL,
|
||||
]);
|
||||
|
||||
$this->pass('Verifying there are no BigPipe placeholders & replacements…', 'Debug');
|
||||
$this->assertEqual('<none>', $this->drupalGetHeader('BigPipe-Test-Placeholders'));
|
||||
$this->pass('Verifying BigPipe start/stop signals are absent…', 'Debug');
|
||||
$this->assertNoRaw(BigPipe::START_SIGNAL, 'BigPipe start signal absent.');
|
||||
$this->assertNoRaw(BigPipe::STOP_SIGNAL, 'BigPipe stop signal absent.');
|
||||
|
||||
$this->pass('Verifying BigPipe assets are absent…', 'Debug');
|
||||
$this->assertTrue(!isset($this->getDrupalSettings()['bigPipePlaceholderIds']) && empty($this->getDrupalSettings()['ajaxPageState']), 'BigPipe drupalSettings and BigPipe asset library absent.');
|
||||
$this->assertRaw('</body>', 'Closing body tag present.');
|
||||
|
||||
// Verify that 4xx responses work fine. (4xx responses are handled by
|
||||
// subrequests to a route pointing to a controller with the desired output.)
|
||||
$this->drupalGet(Url::fromUri('base:non-existing-path'));
|
||||
|
||||
// Simulate development.
|
||||
$this->pass('Verifying BigPipe provides useful error output when an error occurs while rendering a placeholder if verbose error logging is enabled.', 'Debug');
|
||||
$this->config('system.logging')->set('error_level', ERROR_REPORTING_DISPLAY_VERBOSE)->save();
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test'));
|
||||
// The 'edge_case__html_exception' case throws an exception.
|
||||
$this->assertRaw('The website encountered an unexpected error. Please try again later');
|
||||
$this->assertRaw('You are not allowed to say llamas are not cool!');
|
||||
$this->assertNoRaw('</body>', 'Closing body tag absent: error occurred before then.');
|
||||
// The exception is expected. Do not interpret it as a test failure.
|
||||
unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests BigPipe with a multi-occurrence placeholder.
|
||||
*/
|
||||
public function testBigPipeMultiOccurrencePlaceholders() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->assertSessionCookieExists(TRUE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
|
||||
// By not calling performMetaRefresh() here, we simulate JavaScript being
|
||||
// enabled, because as far as the BigPipe module is concerned, JavaScript is
|
||||
// enabled in the browser as long as the BigPipe no-JS cookie is *not* set.
|
||||
// @see setUp()
|
||||
// @see performMetaRefresh()
|
||||
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test_multi_occurrence'));
|
||||
$big_pipe_placeholder_id = 'callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA';
|
||||
$expected_placeholder_replacement = '<script type="application/vnd.drupal-ajax" data-big-pipe-replacement-for-placeholder-with-id="' . $big_pipe_placeholder_id . '">';
|
||||
$this->assertRaw('The count is 1.');
|
||||
$this->assertNoRaw('The count is 2.');
|
||||
$this->assertNoRaw('The count is 3.');
|
||||
$raw_content = $this->getRawContent();
|
||||
$this->assertTrue(substr_count($raw_content, $expected_placeholder_replacement) == 1, 'Only one placeholder replacement was found for the duplicate #lazy_builder arrays.');
|
||||
|
||||
// By calling performMetaRefresh() here, we simulate JavaScript being
|
||||
// disabled, because as far as the BigPipe module is concerned, it is
|
||||
// enabled in the browser when the BigPipe no-JS cookie is set.
|
||||
// @see setUp()
|
||||
// @see performMetaRefresh()
|
||||
$this->performMetaRefresh();
|
||||
$this->assertBigPipeNoJsCookieExists(TRUE);
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test_multi_occurrence'));
|
||||
$this->assertRaw('The count is 1.');
|
||||
$this->assertNoRaw('The count is 2.');
|
||||
$this->assertNoRaw('The count is 3.');
|
||||
}
|
||||
|
||||
protected function assertBigPipeResponseHeadersPresent() {
|
||||
$this->pass('Verifying BigPipe response headers…', 'Debug');
|
||||
$this->assertTrue(FALSE !== strpos($this->drupalGetHeader('Cache-Control'), 'private'), 'Cache-Control header set to "private".');
|
||||
$this->assertEqual('no-store, content="BigPipe/1.0"', $this->drupalGetHeader('Surrogate-Control'));
|
||||
$this->assertEqual('no', $this->drupalGetHeader('X-Accel-Buffering'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts expected BigPipe no-JS placeholders are present and replaced.
|
||||
*
|
||||
* @param array $expected_big_pipe_nojs_placeholders
|
||||
* Keys: BigPipe no-JS placeholder markup. Values: expected replacement
|
||||
* markup.
|
||||
*/
|
||||
protected function assertBigPipeNoJsPlaceholders(array $expected_big_pipe_nojs_placeholders) {
|
||||
$this->pass('Verifying BigPipe no-JS placeholders & replacements…', 'Debug');
|
||||
$this->assertSetsEqual(array_keys($expected_big_pipe_nojs_placeholders), array_map('rawurldecode', explode(' ', $this->drupalGetHeader('BigPipe-Test-No-Js-Placeholders'))));
|
||||
foreach ($expected_big_pipe_nojs_placeholders as $big_pipe_nojs_placeholder => $expected_replacement) {
|
||||
$this->pass('Checking whether the replacement for the BigPipe no-JS placeholder "' . $big_pipe_nojs_placeholder . '" is present:');
|
||||
$this->assertNoRaw($big_pipe_nojs_placeholder);
|
||||
if ($expected_replacement !== NULL) {
|
||||
$this->assertRaw($expected_replacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts expected BigPipe placeholders are present and replaced.
|
||||
*
|
||||
* @param array $expected_big_pipe_placeholders
|
||||
* Keys: BigPipe placeholder IDs. Values: expected AJAX response.
|
||||
* @param array $expected_big_pipe_placeholder_stream_order
|
||||
* Keys: BigPipe placeholder IDs. Values: expected AJAX response. Keys are
|
||||
* defined in the order that they are expected to be rendered & streamed.
|
||||
*/
|
||||
protected function assertBigPipePlaceholders(array $expected_big_pipe_placeholders, array $expected_big_pipe_placeholder_stream_order) {
|
||||
$this->pass('Verifying BigPipe placeholders & replacements…', 'Debug');
|
||||
$this->assertSetsEqual(array_keys($expected_big_pipe_placeholders), explode(' ', $this->drupalGetHeader('BigPipe-Test-Placeholders')));
|
||||
$placeholder_positions = [];
|
||||
$placeholder_replacement_positions = [];
|
||||
foreach ($expected_big_pipe_placeholders as $big_pipe_placeholder_id => $expected_ajax_response) {
|
||||
$this->pass('BigPipe placeholder: ' . $big_pipe_placeholder_id, 'Debug');
|
||||
// Verify expected placeholder.
|
||||
$expected_placeholder_html = '<span data-big-pipe-placeholder-id="' . $big_pipe_placeholder_id . '"></span>';
|
||||
$this->assertRaw($expected_placeholder_html, 'BigPipe placeholder for placeholder ID "' . $big_pipe_placeholder_id . '" found.');
|
||||
$pos = strpos($this->getRawContent(), $expected_placeholder_html);
|
||||
$placeholder_positions[$pos] = $big_pipe_placeholder_id;
|
||||
// Verify expected placeholder replacement.
|
||||
$expected_placeholder_replacement = '<script type="application/vnd.drupal-ajax" data-big-pipe-replacement-for-placeholder-with-id="' . $big_pipe_placeholder_id . '">';
|
||||
$result = $this->xpath('//script[@data-big-pipe-replacement-for-placeholder-with-id=:id]', [':id' => Html::decodeEntities($big_pipe_placeholder_id)]);
|
||||
if ($expected_ajax_response === NULL) {
|
||||
$this->assertEqual(0, count($result));
|
||||
$this->assertNoRaw($expected_placeholder_replacement);
|
||||
continue;
|
||||
}
|
||||
$this->assertEqual($expected_ajax_response, trim($result[0]->getText()));
|
||||
$this->assertRaw($expected_placeholder_replacement);
|
||||
$pos = strpos($this->getRawContent(), $expected_placeholder_replacement);
|
||||
$placeholder_replacement_positions[$pos] = $big_pipe_placeholder_id;
|
||||
}
|
||||
ksort($placeholder_positions, SORT_NUMERIC);
|
||||
$this->assertEqual(array_keys($expected_big_pipe_placeholders), array_values($placeholder_positions));
|
||||
$placeholders = array_map(function (NodeElement $element) {
|
||||
return $element->getAttribute('data-big-pipe-placeholder-id');
|
||||
}, $this->cssSelect('[data-big-pipe-placeholder-id]'));
|
||||
$this->assertEqual(count($expected_big_pipe_placeholders), count(array_unique($placeholders)));
|
||||
$expected_big_pipe_placeholders_with_replacements = [];
|
||||
foreach ($expected_big_pipe_placeholder_stream_order as $big_pipe_placeholder_id) {
|
||||
$expected_big_pipe_placeholders_with_replacements[$big_pipe_placeholder_id] = $expected_big_pipe_placeholders[$big_pipe_placeholder_id];
|
||||
}
|
||||
$this->assertEqual($expected_big_pipe_placeholders_with_replacements, array_filter($expected_big_pipe_placeholders));
|
||||
$this->assertSetsEqual(array_keys($expected_big_pipe_placeholders_with_replacements), array_values($placeholder_replacement_positions));
|
||||
$this->assertEqual(count($expected_big_pipe_placeholders_with_replacements), preg_match_all('/' . preg_quote('<script type="application/vnd.drupal-ajax" data-big-pipe-replacement-for-placeholder-with-id="', '/') . '/', $this->getRawContent()));
|
||||
|
||||
$this->pass('Verifying BigPipe start/stop signals…', 'Debug');
|
||||
$this->assertRaw(BigPipe::START_SIGNAL, 'BigPipe start signal present.');
|
||||
$this->assertRaw(BigPipe::STOP_SIGNAL, 'BigPipe stop signal present.');
|
||||
$start_signal_position = strpos($this->getRawContent(), BigPipe::START_SIGNAL);
|
||||
$stop_signal_position = strpos($this->getRawContent(), BigPipe::STOP_SIGNAL);
|
||||
$this->assertTrue($start_signal_position < $stop_signal_position, 'BigPipe start signal appears before stop signal.');
|
||||
|
||||
$this->pass('Verifying BigPipe placeholder replacements and start/stop signals were streamed in the correct order…', 'Debug');
|
||||
$expected_stream_order = array_keys($expected_big_pipe_placeholders_with_replacements);
|
||||
array_unshift($expected_stream_order, BigPipe::START_SIGNAL);
|
||||
array_push($expected_stream_order, BigPipe::STOP_SIGNAL);
|
||||
$actual_stream_order = $placeholder_replacement_positions + [
|
||||
$start_signal_position => BigPipe::START_SIGNAL,
|
||||
$stop_signal_position => BigPipe::STOP_SIGNAL,
|
||||
];
|
||||
ksort($actual_stream_order, SORT_NUMERIC);
|
||||
$this->assertEqual($expected_stream_order, array_values($actual_stream_order));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures CSRF tokens can be generated for the current user's session.
|
||||
*/
|
||||
protected function setCsrfTokenSeedInTestEnvironment() {
|
||||
$session_data = $this->container->get('session_handler.write_safe')->read($this->getSession()->getCookie($this->getSessionName()));
|
||||
$csrf_token_seed = unserialize(explode('_sf2_meta|', $session_data)[1])['s'];
|
||||
$this->container->get('session_manager.metadata_bag')->setCsrfTokenSeed($csrf_token_seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Drupal\big_pipe_test\BigPipePlaceholderTestCase[]
|
||||
*/
|
||||
protected function getTestCases($has_session = TRUE) {
|
||||
return BigPipePlaceholderTestCases::cases($this->container, $this->rootUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts whether arrays A and B are equal, when treated as sets.
|
||||
*/
|
||||
protected function assertSetsEqual(array $a, array $b) {
|
||||
return count($a) == count($b) && !array_diff_assoc($a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts whether a BigPipe no-JS cookie exists or not.
|
||||
*/
|
||||
protected function assertBigPipeNoJsCookieExists($expected) {
|
||||
$this->assertCookieExists('big_pipe_nojs', $expected, 'BigPipe no-JS');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts whether a session cookie exists or not.
|
||||
*/
|
||||
protected function assertSessionCookieExists($expected) {
|
||||
$this->assertCookieExists($this->getSessionName(), $expected, 'Session');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts whether a cookie exists on the client or not.
|
||||
*/
|
||||
protected function assertCookieExists($cookie_name, $expected, $cookie_label) {
|
||||
$this->assertEqual($expected, !empty($this->getSession()->getCookie($cookie_name)), $expected ? "$cookie_label cookie exists." : "$cookie_label cookie does not exist.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls ::performMetaRefresh() and asserts the responses.
|
||||
*/
|
||||
protected function assertBigPipeNoJsMetaRefreshRedirect() {
|
||||
$original_url = $this->getSession()->getCurrentUrl();
|
||||
|
||||
// Disable automatic following of redirects by the HTTP client, so that this
|
||||
// test can analyze the response headers of each redirect response.
|
||||
$this->getSession()->getDriver()->getClient()->followRedirects(FALSE);
|
||||
$this->performMetaRefresh();
|
||||
$headers[0] = $this->getSession()->getResponseHeaders();
|
||||
$statuses[0] = $this->getSession()->getStatusCode();
|
||||
$this->performMetaRefresh();
|
||||
$headers[1] = $this->getSession()->getResponseHeaders();
|
||||
$statuses[1] = $this->getSession()->getStatusCode();
|
||||
$this->getSession()->getDriver()->getClient()->followRedirects(TRUE);
|
||||
|
||||
$this->assertEqual($original_url, $this->getSession()->getCurrentUrl(), 'Redirected back to the original location.');
|
||||
|
||||
// First response: redirect.
|
||||
$this->assertEqual(302, $statuses[0], 'The first response was a 302 (redirect).');
|
||||
$this->assertIdentical(0, strpos($headers[0]['Set-Cookie'][0], 'big_pipe_nojs=1'), 'The first response sets the big_pipe_nojs cookie.');
|
||||
$this->assertEqual($original_url, $headers[0]['Location'][0], 'The first response redirected back to the original page.');
|
||||
$this->assertTrue(empty(array_diff(['cookies:big_pipe_nojs', 'session.exists'], explode(' ', $headers[0]['X-Drupal-Cache-Contexts'][0]))), 'The first response varies by the "cookies:big_pipe_nojs" and "session.exists" cache contexts.');
|
||||
$this->assertFalse(isset($headers[0]['Surrogate-Control']), 'The first response has no "Surrogate-Control" header.');
|
||||
|
||||
// Second response: redirect followed.
|
||||
$this->assertEqual(200, $statuses[1], 'The second response was a 200.');
|
||||
$this->assertTrue(empty(array_diff(['cookies:big_pipe_nojs', 'session.exists'], explode(' ', $headers[0]['X-Drupal-Cache-Contexts'][0]))), 'The first response varies by the "cookies:big_pipe_nojs" and "session.exists" cache contexts.');
|
||||
$this->assertEqual('no-store, content="BigPipe/1.0"', $headers[1]['Surrogate-Control'][0], 'The second response has a "Surrogate-Control" header.');
|
||||
|
||||
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=', 'Once the BigPipe no-JS cookie is set, the <meta> refresh is absent: only one redirect ever happens.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Drupal\Tests\big_pipe\Unit\Render\Placeholder;
|
||||
|
||||
use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
|
||||
use Drupal\big_pipe\Tests\BigPipePlaceholderTestCases;
|
||||
use Drupal\big_pipe_test\BigPipePlaceholderTestCases;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Session\SessionConfigurationInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
@@ -47,7 +47,7 @@ class BigPipeStrategyTest extends UnitTestCase {
|
||||
$big_pipe_strategy = new BigPipeStrategy($session_configuration->reveal(), $request_stack->reveal(), $route_match->reveal());
|
||||
$processed_placeholders = $big_pipe_strategy->processPlaceholders($placeholders);
|
||||
|
||||
if ($request->isMethodSafe() && !$route_match_has_no_big_pipe_option && $request_has_session) {
|
||||
if ($request->isMethodCacheable() && !$route_match_has_no_big_pipe_option && $request_has_session) {
|
||||
$this->assertSameSize($expected_big_pipe_placeholders, $processed_placeholders, 'BigPipe is able to deliver all placeholders.');
|
||||
foreach (array_keys($placeholders) as $placeholder) {
|
||||
$this->assertSame($expected_big_pipe_placeholders[$placeholder], $processed_placeholders[$placeholder], "Verifying how BigPipeStrategy handles the placeholder '$placeholder'");
|
||||
@@ -59,7 +59,7 @@ class BigPipeStrategyTest extends UnitTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\big_pipe\Tests\BigPipePlaceholderTestCases
|
||||
* @see \Drupal\big_pipe_test\BigPipePlaceholderTestCases
|
||||
*/
|
||||
public function placeholdersProvider() {
|
||||
$cases = BigPipePlaceholderTestCases::cases();
|
||||
@@ -83,25 +83,29 @@ class BigPipeStrategyTest extends UnitTestCase {
|
||||
'_no_big_pipe present, no session, no-JS cookie present' => [$placeholders, 'GET', TRUE, FALSE, TRUE, []],
|
||||
'_no_big_pipe present, session, no-JS cookie absent' => [$placeholders, 'GET', TRUE, TRUE, FALSE, []],
|
||||
'_no_big_pipe present, session, no-JS cookie present' => [$placeholders, 'GET', TRUE, TRUE, TRUE, []],
|
||||
'_no_big_pipe absent, session, no-JS cookie absent: (JS-powered) BigPipe placeholder used for HTML placeholders' => [$placeholders, 'GET', FALSE, TRUE, FALSE, [
|
||||
$cases['html']->placeholder => $cases['html']->bigPipePlaceholderRenderArray,
|
||||
$cases['html_attribute_value']->placeholder => $cases['html_attribute_value']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['html_attribute_value_subset']->placeholder => $cases['html_attribute_value_subset']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['edge_case__invalid_html']->placeholder => $cases['edge_case__invalid_html']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['edge_case__html_non_lazy_builder']->placeholder => $cases['edge_case__html_non_lazy_builder']->bigPipePlaceholderRenderArray,
|
||||
$cases['exception__lazy_builder']->placeholder => $cases['exception__lazy_builder']->bigPipePlaceholderRenderArray,
|
||||
$cases['exception__embedded_response']->placeholder => $cases['exception__embedded_response']->bigPipePlaceholderRenderArray,
|
||||
]],
|
||||
'_no_big_pipe absent, session, no-JS cookie absent: (JS-powered) BigPipe placeholder used for HTML placeholders' => [
|
||||
$placeholders, 'GET', FALSE, TRUE, FALSE, [
|
||||
$cases['html']->placeholder => $cases['html']->bigPipePlaceholderRenderArray,
|
||||
$cases['html_attribute_value']->placeholder => $cases['html_attribute_value']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['html_attribute_value_subset']->placeholder => $cases['html_attribute_value_subset']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['edge_case__invalid_html']->placeholder => $cases['edge_case__invalid_html']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['edge_case__html_non_lazy_builder']->placeholder => $cases['edge_case__html_non_lazy_builder']->bigPipePlaceholderRenderArray,
|
||||
$cases['exception__lazy_builder']->placeholder => $cases['exception__lazy_builder']->bigPipePlaceholderRenderArray,
|
||||
$cases['exception__embedded_response']->placeholder => $cases['exception__embedded_response']->bigPipePlaceholderRenderArray,
|
||||
],
|
||||
],
|
||||
'_no_big_pipe absent, session, no-JS cookie absent: (JS-powered) BigPipe placeholder used for HTML placeholders — but unsafe method' => [$placeholders, 'POST', FALSE, TRUE, FALSE, []],
|
||||
'_no_big_pipe absent, session, no-JS cookie present: no-JS BigPipe placeholder used for HTML placeholders' => [$placeholders, 'GET', FALSE, TRUE, TRUE, [
|
||||
$cases['html']->placeholder => $cases['html']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['html_attribute_value']->placeholder => $cases['html_attribute_value']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['html_attribute_value_subset']->placeholder => $cases['html_attribute_value_subset']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['edge_case__invalid_html']->placeholder => $cases['edge_case__invalid_html']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['edge_case__html_non_lazy_builder']->placeholder => $cases['edge_case__html_non_lazy_builder']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['exception__lazy_builder']->placeholder => $cases['exception__lazy_builder']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['exception__embedded_response']->placeholder => $cases['exception__embedded_response']->bigPipeNoJsPlaceholderRenderArray,
|
||||
]],
|
||||
'_no_big_pipe absent, session, no-JS cookie present: no-JS BigPipe placeholder used for HTML placeholders' => [
|
||||
$placeholders, 'GET', FALSE, TRUE, TRUE, [
|
||||
$cases['html']->placeholder => $cases['html']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['html_attribute_value']->placeholder => $cases['html_attribute_value']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['html_attribute_value_subset']->placeholder => $cases['html_attribute_value_subset']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['edge_case__invalid_html']->placeholder => $cases['edge_case__invalid_html']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['edge_case__html_non_lazy_builder']->placeholder => $cases['edge_case__html_non_lazy_builder']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['exception__lazy_builder']->placeholder => $cases['exception__lazy_builder']->bigPipeNoJsPlaceholderRenderArray,
|
||||
$cases['exception__embedded_response']->placeholder => $cases['exception__embedded_response']->bigPipeNoJsPlaceholderRenderArray,
|
||||
],
|
||||
],
|
||||
'_no_big_pipe absent, session, no-JS cookie present: no-JS BigPipe placeholder used for HTML placeholders — but unsafe method' => [$placeholders, 'POST', FALSE, TRUE, TRUE, []],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ description: 'Theme for testing BigPipe edge cases.'
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
Reference in New Issue
Block a user