Revert "Issue #2678568 by Wim Leers: Ensure good UX & DX even when A) rendering of placeholder fails, B) some response event subscriber fails"
This reverts commit eee3500713
.
8.2.x
parent
5f65d69356
commit
ce13a0580f
|
@ -205,12 +205,6 @@ class BigPipe implements BigPipeInterface {
|
|||
* @param \Drupal\Core\Asset\AttachedAssetsInterface $cumulative_assets
|
||||
* The cumulative assets sent so far; to be updated while rendering no-JS
|
||||
* BigPipe placeholders.
|
||||
*
|
||||
* @throws \Exception
|
||||
* If an exception is thrown during the rendering of a placeholder, it is
|
||||
* caught to allow the other placeholders to still be replaced. But when
|
||||
* error logging is configured to be verbose, the exception is rethrown to
|
||||
* simplify debugging.
|
||||
*/
|
||||
protected function sendNoJsPlaceholders($html, $no_js_placeholders, AttachedAssetsInterface $cumulative_assets) {
|
||||
// Split the HTML on every no-JS placeholder string.
|
||||
|
@ -244,19 +238,7 @@ class BigPipe implements BigPipeInterface {
|
|||
],
|
||||
],
|
||||
];
|
||||
try {
|
||||
$elements = $this->renderPlaceholder($placeholder, $placeholder_plus_cumulative_settings);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
if (\Drupal::config('system.logging')->get('error_level') === ERROR_REPORTING_DISPLAY_VERBOSE) {
|
||||
throw $e;
|
||||
}
|
||||
else {
|
||||
trigger_error($e, E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$elements = $this->renderPlaceholder($placeholder, $placeholder_plus_cumulative_settings);
|
||||
|
||||
// Create a new HtmlResponse. Ensure the CSS and (non-bottom) JS is sent
|
||||
// before the HTML they're associated with. In other words: ensure the
|
||||
|
@ -281,19 +263,7 @@ class BigPipe implements BigPipeInterface {
|
|||
// - the HTML to load the JS (at the top) can be rendered.
|
||||
$fake_request = $this->requestStack->getMasterRequest()->duplicate();
|
||||
$fake_request->request->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())]);
|
||||
try {
|
||||
$html_response = $this->filterEmbeddedResponse($fake_request, $html_response);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
if (\Drupal::config('system.logging')->get('error_level') === ERROR_REPORTING_DISPLAY_VERBOSE) {
|
||||
throw $e;
|
||||
}
|
||||
else {
|
||||
trigger_error($e, E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$html_response = $this->filterEmbeddedResponse($fake_request, $html_response);
|
||||
|
||||
// Send this embedded HTML response.
|
||||
print $html_response->getContent();
|
||||
|
@ -320,12 +290,6 @@ class BigPipe implements BigPipeInterface {
|
|||
* @param \Drupal\Core\Asset\AttachedAssetsInterface $cumulative_assets
|
||||
* The cumulative assets sent so far; to be updated while rendering BigPipe
|
||||
* placeholders.
|
||||
*
|
||||
* @throws \Exception
|
||||
* If an exception is thrown during the rendering of a placeholder, it is
|
||||
* caught to allow the other placeholders to still be replaced. But when
|
||||
* error logging is configured to be verbose, the exception is rethrown to
|
||||
* simplify debugging.
|
||||
*/
|
||||
protected function sendPlaceholders(array $placeholders, array $placeholder_order, AttachedAssetsInterface $cumulative_assets) {
|
||||
// Return early if there are no BigPipe placeholders to send.
|
||||
|
@ -356,18 +320,7 @@ class BigPipe implements BigPipeInterface {
|
|||
|
||||
// Render the placeholder.
|
||||
$placeholder_render_array = $placeholders[$placeholder_id];
|
||||
try {
|
||||
$elements = $this->renderPlaceholder($placeholder_id, $placeholder_render_array);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
if (\Drupal::config('system.logging')->get('error_level') === ERROR_REPORTING_DISPLAY_VERBOSE) {
|
||||
throw $e;
|
||||
}
|
||||
else {
|
||||
trigger_error($e, E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$elements = $this->renderPlaceholder($placeholder_id, $placeholder_render_array);
|
||||
|
||||
// Create a new AjaxResponse.
|
||||
$ajax_response = new AjaxResponse();
|
||||
|
@ -389,18 +342,7 @@ class BigPipe implements BigPipeInterface {
|
|||
// allows us to track the total set of asset libraries sent in the
|
||||
// initial HTML response plus all embedded AJAX responses sent so far.
|
||||
$fake_request->request->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())] + $cumulative_assets->getSettings()['ajaxPageState']);
|
||||
try {
|
||||
$ajax_response = $this->filterEmbeddedResponse($fake_request, $ajax_response);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
if (\Drupal::config('system.logging')->get('error_level') === ERROR_REPORTING_DISPLAY_VERBOSE) {
|
||||
throw $e;
|
||||
}
|
||||
else {
|
||||
trigger_error($e, E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$ajax_response = $this->filterEmbeddedResponse($fake_request, $ajax_response);
|
||||
|
||||
// Send this embedded AJAX response.
|
||||
$json = $ajax_response->getContent();
|
||||
|
|
|
@ -260,94 +260,12 @@ class BigPipePlaceholderTestCases {
|
|||
$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="68a75f1a"></drupal-render-placeholder>',
|
||||
[
|
||||
'#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::exception', ['llamas', 'suck']],
|
||||
]
|
||||
);
|
||||
$exception->bigPipePlaceholderId = 'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args[0]=llamas&args[1]=suck&token=68a75f1a';
|
||||
$exception->bigPipePlaceholderRenderArray = [
|
||||
'#markup' => '<div data-big-pipe-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args[0]=llamas&args[1]=suck&token=68a75f1a"></div>',
|
||||
'#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[0]=llamas&args[1]=suck&token=68a75f1a' => TRUE,
|
||||
],
|
||||
],
|
||||
'big_pipe_placeholders' => [
|
||||
'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args[0]=llamas&args[1]=suck&token=68a75f1a' => $exception->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$exception->embeddedAjaxResponseCommands = NULL;
|
||||
$exception->bigPipeNoJsPlaceholder = '<div data-big-pipe-nojs-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args[0]=llamas&args[1]=suck&token=68a75f1a"></div>';
|
||||
$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="2a9bd022"></drupal-render-placeholder>',
|
||||
[
|
||||
'#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::responseException', []],
|
||||
]
|
||||
);
|
||||
$embedded_response_exception->bigPipePlaceholderId = 'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=2a9bd022';
|
||||
$embedded_response_exception->bigPipePlaceholderRenderArray = [
|
||||
'#markup' => '<div data-big-pipe-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=2a9bd022"></div>',
|
||||
'#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=2a9bd022' => TRUE,
|
||||
],
|
||||
],
|
||||
'big_pipe_placeholders' => [
|
||||
'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=2a9bd022' => $embedded_response_exception->placeholderRenderArray,
|
||||
],
|
||||
],
|
||||
];
|
||||
$embedded_response_exception->embeddedAjaxResponseCommands = NULL;
|
||||
$embedded_response_exception->bigPipeNoJsPlaceholder = '<div data-big-pipe-nojs-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=2a9bd022"></div>';
|
||||
$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,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
|
|||
use Drupal\big_pipe\Render\BigPipe;
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Logger\RfcLogLevel;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
|
@ -33,7 +32,7 @@ class BigPipeTest extends WebTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['big_pipe', 'big_pipe_test', 'dblog'];
|
||||
public static $modules = ['big_pipe', 'big_pipe_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -122,13 +121,13 @@ class BigPipeTest extends WebTestBase {
|
|||
$this->cookies = [];
|
||||
|
||||
// Edge case: route with '_no_big_pipe' option.
|
||||
$this->drupalGet(Url::fromRoute('no_big_pipe'));
|
||||
$this->drupalGet(Url::fromRoute('big_pipe_test.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->drupalGet(Url::fromRoute('big_pipe_test.no_big_pipe'));
|
||||
$this->assertSessionCookieExists(TRUE);
|
||||
$this->assertBigPipeNoJsCookieExists(FALSE);
|
||||
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
|
||||
|
@ -146,15 +145,10 @@ class BigPipeTest extends WebTestBase {
|
|||
* @see \Drupal\big_pipe\Tests\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.
|
||||
|
@ -173,39 +167,15 @@ class BigPipeTest extends WebTestBase {
|
|||
$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,
|
||||
]);
|
||||
|
||||
$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'], "exception 'Exception' with message 'Oh noes!'"));
|
||||
$this->assertEqual(RfcLogLevel::ERROR, $records[0]->severity);
|
||||
$this->assertTrue(FALSE !== strpos((string) unserialize($records[1]->variables)['@message'], "exception 'Exception' with 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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,9 +189,6 @@ class BigPipeTest extends WebTestBase {
|
|||
* @see \Drupal\big_pipe\Tests\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);
|
||||
|
@ -244,8 +211,6 @@ class BigPipeTest extends WebTestBase {
|
|||
$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');
|
||||
|
@ -256,22 +221,10 @@ class BigPipeTest extends WebTestBase {
|
|||
|
||||
$this->pass('Verifying BigPipe assets are absent…', 'Debug');
|
||||
$this->assertFalse(empty($this->getDrupalSettings()), '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');
|
||||
}
|
||||
|
||||
protected function assertBigPipeResponseHeadersPresent() {
|
||||
|
@ -293,10 +246,7 @@ class BigPipeTest extends WebTestBase {
|
|||
$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);
|
||||
}
|
||||
$this->assertRaw($expected_replacement);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,14 +269,9 @@ class BigPipeTest extends WebTestBase {
|
|||
$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((string) $result[0]));
|
||||
$expected_placeholder_replacement = '<script type="application/vnd.drupal-ajax" data-big-pipe-replacement-for-placeholder-with-id="' . $big_pipe_placeholder_id . '">';
|
||||
$this->assertRaw($expected_placeholder_replacement);
|
||||
$pos = strpos($this->getRawContent(), $expected_placeholder_replacement);
|
||||
$placeholder_replacement_positions[$pos] = $big_pipe_placeholder_id;
|
||||
|
@ -334,9 +279,8 @@ class BigPipeTest extends WebTestBase {
|
|||
ksort($placeholder_positions, SORT_NUMERIC);
|
||||
$this->assertEqual(array_keys($expected_big_pipe_placeholders), array_values($placeholder_positions));
|
||||
$this->assertEqual(count($expected_big_pipe_placeholders), preg_match_all('/' . preg_quote('<div data-big-pipe-placeholder-id="', '/') . '/', $this->getRawContent()));
|
||||
$expected_big_pipe_placeholders_with_replacements = array_filter($expected_big_pipe_placeholders);
|
||||
$this->assertEqual(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->assertEqual(array_keys($expected_big_pipe_placeholders), array_values($placeholder_replacement_positions));
|
||||
$this->assertEqual(count($expected_big_pipe_placeholders), 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.');
|
||||
|
@ -346,7 +290,7 @@ class BigPipeTest extends WebTestBase {
|
|||
$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);
|
||||
$expected_stream_order = array_keys($expected_big_pipe_placeholders);
|
||||
array_unshift($expected_stream_order, BigPipe::START_SIGNAL);
|
||||
array_push($expected_stream_order, BigPipe::STOP_SIGNAL);
|
||||
$actual_stream_order = $placeholder_replacement_positions + [
|
||||
|
|
|
@ -6,11 +6,11 @@ big_pipe_test:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
no_big_pipe:
|
||||
big_pipe_test.no_big_pipe:
|
||||
path: '/no_big_pipe'
|
||||
defaults:
|
||||
_controller: '\Drupal\big_pipe_test\BigPipeTestController::nope'
|
||||
_title: '_no_big_pipe route option test'
|
||||
_controller: '\Drupal\big_pipe_test\BigPipeTestController::test'
|
||||
_title: 'BigPipe test'
|
||||
options:
|
||||
_no_big_pipe: TRUE
|
||||
requirements:
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace Drupal\big_pipe_test;
|
||||
|
||||
use Drupal\big_pipe\Render\BigPipeMarkup;
|
||||
use Drupal\big_pipe_test\EventSubscriber\BigPipeTestSubscriber;
|
||||
|
||||
class BigPipeTestController {
|
||||
|
||||
|
@ -35,22 +34,9 @@ class BigPipeTestController {
|
|||
// 5. Edge case: non-#lazy_builder placeholder.
|
||||
$build['edge_case__html_non_lazy_builder'] = $cases['edge_case__html_non_lazy_builder']->renderArray;
|
||||
|
||||
// 6. Exception: #lazy_builder that throws an exception.
|
||||
$build['exception__lazy_builder'] = $cases['exception__lazy_builder']->renderArray;
|
||||
|
||||
// 7. Exception: placeholder that causes response filter to throw exception.
|
||||
$build['exception__embedded_response'] = $cases['exception__embedded_response']->renderArray;
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function nope() {
|
||||
return ['#markup' => '<p>Nope.</p>'];
|
||||
}
|
||||
|
||||
/**
|
||||
* #lazy_builder callback; builds <time> markup with current time.
|
||||
*
|
||||
|
@ -77,24 +63,4 @@ class BigPipeTestController {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* #lazy_builder callback; throws exception.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function exception() {
|
||||
throw new \Exception('You are not allowed to say llamas are not cool!');
|
||||
}
|
||||
|
||||
/**
|
||||
* #lazy_builder callback; returns content that will trigger an exception.
|
||||
*
|
||||
* @see \Drupal\big_pipe_test\EventSubscriber\BigPipeTestSubscriber::onRespondTriggerException()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function responseException() {
|
||||
return ['#plain_text' => BigPipeTestSubscriber::CONTENT_TRIGGER_EXCEPTION];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\big_pipe_test\EventSubscriber;
|
||||
|
||||
use Drupal\Core\Render\AttachmentsInterface;
|
||||
use Drupal\Core\Render\HtmlResponse;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
@ -15,45 +14,13 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|||
|
||||
class BigPipeTestSubscriber implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* @see \Drupal\big_pipe_test\BigPipeTestController::responseException()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const CONTENT_TRIGGER_EXCEPTION = 'NOPE!NOPE!NOPE!';
|
||||
|
||||
/**
|
||||
* Triggers exception for embedded HTML/AJAX responses with certain content.
|
||||
*
|
||||
* @see \Drupal\big_pipe_test\BigPipeTestController::responseException()
|
||||
*
|
||||
* @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
|
||||
* The event to process.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function onRespondTriggerException(FilterResponseEvent $event) {
|
||||
$response = $event->getResponse();
|
||||
|
||||
if (!$response instanceof AttachmentsInterface) {
|
||||
return;
|
||||
}
|
||||
|
||||
$attachments = $response->getAttachments();
|
||||
if (!isset($attachments['big_pipe_placeholders']) && !isset($attachments['big_pipe_nojs_placeholders'])) {
|
||||
if (strpos($response->getContent(), static::CONTENT_TRIGGER_EXCEPTION) !== FALSE) {
|
||||
throw new \Exception('Oh noes!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes all BigPipe placeholders (JS and no-JS) via headers for testing.
|
||||
*
|
||||
* @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
|
||||
* The event to process.
|
||||
*/
|
||||
public function onRespondSetBigPipeDebugPlaceholderHeaders(FilterResponseEvent $event) {
|
||||
public function onRespond(FilterResponseEvent $event) {
|
||||
$response = $event->getResponse();
|
||||
if (!$response instanceof HtmlResponse) {
|
||||
return;
|
||||
|
@ -77,11 +44,8 @@ class BigPipeTestSubscriber implements EventSubscriberInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
// Run just before \Drupal\big_pipe\EventSubscriber\HtmlResponseBigPipeSubscriber::onRespond().
|
||||
$events[KernelEvents::RESPONSE][] = ['onRespondSetBigPipeDebugPlaceholderHeaders', -9999];
|
||||
|
||||
// Run just after \Drupal\big_pipe\EventSubscriber\HtmlResponseBigPipeSubscriber::onRespond().
|
||||
$events[KernelEvents::RESPONSE][] = ['onRespondTriggerException', -10001];
|
||||
// Run *just* before \Drupal\big_pipe\EventSubscriber\HtmlResponseBigPipeSubscriber::onRespond().
|
||||
$events[KernelEvents::RESPONSE][] = ['onRespond', -99999];
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
|
|
@ -75,8 +75,6 @@ class BigPipeStrategyTest extends UnitTestCase {
|
|||
$cases['html_attribute_value_subset']->placeholder => $cases['html_attribute_value_subset']->placeholderRenderArray,
|
||||
$cases['edge_case__invalid_html']->placeholder => $cases['edge_case__invalid_html']->placeholderRenderArray,
|
||||
$cases['edge_case__html_non_lazy_builder']->placeholder => $cases['edge_case__html_non_lazy_builder']->placeholderRenderArray,
|
||||
$cases['exception__lazy_builder']->placeholder => $cases['exception__lazy_builder']->placeholderRenderArray,
|
||||
$cases['exception__embedded_response']->placeholder => $cases['exception__embedded_response']->placeholderRenderArray,
|
||||
];
|
||||
|
||||
return [
|
||||
|
@ -92,8 +90,6 @@ class BigPipeStrategyTest extends UnitTestCase {
|
|||
$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 present: no-JS BigPipe placeholder used for HTML placeholders' => [$placeholders, FALSE, TRUE, TRUE, [
|
||||
$cases['html']->placeholder => $cases['html']->bigPipeNoJsPlaceholderRenderArray,
|
||||
|
@ -101,8 +97,6 @@ class BigPipeStrategyTest extends UnitTestCase {
|
|||
$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,
|
||||
]],
|
||||
];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue