function BigPipeTest::testBigPipe
Same name in other branches
- 9 core/modules/big_pipe/tests/src/Functional/BigPipeTest.php \Drupal\Tests\big_pipe\Functional\BigPipeTest::testBigPipe()
- 8.9.x core/modules/big_pipe/tests/src/Functional/BigPipeTest.php \Drupal\Tests\big_pipe\Functional\BigPipeTest::testBigPipe()
- 10 core/modules/big_pipe/tests/src/Functional/BigPipeTest.php \Drupal\Tests\big_pipe\Functional\BigPipeTest::testBigPipe()
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 also
\Drupal\big_pipe_test\BigPipePlaceholderTestCases
File
-
core/
modules/ big_pipe/ tests/ src/ Functional/ BigPipeTest.php, line 143
Class
- BigPipeTest
- Tests BigPipe's no-JS detection & response delivery (with and without JS).
Namespace
Drupal\Tests\big_pipe\FunctionalCode
public function testBigPipe() : void {
// Simulate production.
$this->config('system.logging')
->set('error_level', ERROR_REPORTING_HIDE)
->save();
$this->drupalLogin($this->rootUser);
$this->assertSessionCookieExists('1');
$this->assertBigPipeNoJsCookieExists('0');
$connection = Database::getConnection();
$log_count = $connection->select('watchdog')
->countQuery()
->execute()
->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->assertSession()
->responseHeaderNotContains('X-Drupal-Cache-Tags', '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_suspend']->bigPipePlaceholderId => Json::encode($cases['edge_case__html_non_lazy_builder_suspend']->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['html']->bigPipePlaceholderId,
1 => $cases['edge_case__html_non_lazy_builder']->bigPipePlaceholderId,
// The suspended placeholder is replaced after the non-suspended
// placeholder even though it appears first in the page.
// @see Drupal\big_pipe\Render\BigPipe\Render::sendPlaceholders()
2 => $cases['edge_case__html_non_lazy_builder_suspend']->bigPipePlaceholderId,
]);
$this->assertSession()
->responseContains('</body>');
// Verifying BigPipe assets are present.
$this->assertNotEmpty($this->getDrupalSettings());
$this->assertContains('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->assertEquals($log_count + 2, (int) $connection->select('watchdog')
->countQuery()
->execute()
->fetchField(), 'Two new watchdog entries.');
// Using dynamic select queries with the method range() allows contrib
// database drivers the ability to insert their own limit and offset
// functionality.
$records = $connection->select('watchdog', 'w')
->fields('w')
->orderBy('wid', 'DESC')
->range(0, 2)
->execute()
->fetchAll();
$this->assertEquals(RfcLogLevel::ERROR, $records[0]->severity);
$this->assertStringContainsString('Oh noes!', (string) unserialize($records[0]->variables)['@message']);
$this->assertEquals(RfcLogLevel::ERROR, $records[1]->severity);
$this->assertStringContainsString('You are not allowed to say llamas are not cool!', (string) unserialize($records[1]->variables)['@message']);
// 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.
// Verifying BigPipe provides useful error output when an error occurs
// while rendering a placeholder if verbose error logging is enabled.
$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->assertSession()
->pageTextContains('The website encountered an unexpected error. Try again later');
$this->assertSession()
->pageTextContains('You are not allowed to say llamas are not cool!');
// Check that stop signal and closing body tag are absent.
$this->assertSession()
->responseNotContains(BigPipe::STOP_SIGNAL);
$this->assertSession()
->responseNotContains('</body>');
// The exception is expected. Do not interpret it as a test failure.
unlink($this->root . '/' . $this->siteDirectory . '/error.log');
// Tests the enforced redirect response exception handles redirecting to
// a trusted redirect.
$this->drupalGet(Url::fromRoute('big_pipe_test_trusted_redirect'));
$this->assertSession()
->responseContains('application/vnd.drupal-ajax');
$this->assertSession()
->responseContains('[{"command":"redirect","url":"\\/big_pipe_test"}]');
// Test that it rejects an untrusted redirect.
$this->drupalGet(Url::fromRoute('big_pipe_test_untrusted_redirect'));
$this->assertSession()
->responseContains('Redirects to external URLs are not allowed by default');
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.