function RendererBubblingTest::testBubblingWithPrerender

Same name and namespace in other branches
  1. 9 core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php \Drupal\Tests\Core\Render\RendererBubblingTest::testBubblingWithPrerender()
  2. 8.9.x core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php \Drupal\Tests\Core\Render\RendererBubblingTest::testBubblingWithPrerender()
  3. 11.x core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php \Drupal\Tests\Core\Render\RendererBubblingTest::testBubblingWithPrerender()

Tests bubbling of bubbleable metadata added by #pre_render callbacks.

@dataProvider providerTestBubblingWithPrerender

File

core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php, line 448

Class

RendererBubblingTest
@coversDefaultClass \Drupal\Core\Render\Renderer[[api-linebreak]] @group Render

Namespace

Drupal\Tests\Core\Render

Code

public function testBubblingWithPrerender($test_element) : void {
  $this->setUpRequest();
  $this->setUpMemoryCache();
  // Mock the State service.
  $time = $this->prophesize(TimeInterface::class)
    ->reveal();
  $memory_state = new State(new KeyValueMemoryFactory(), new MemoryBackend($time), new NullLockBackend());
  \Drupal::getContainer()->set('state', $memory_state);
  // Simulate the theme system/Twig: a recursive call to Renderer::render(),
  // just like the theme system or a Twig template would have done.
  $this->themeManager
    ->expects($this->any())
    ->method('render')
    ->willReturnCallback(function ($hook, $vars) {
    return $this->renderer
      ->render($vars['foo']);
  });
  // ::bubblingPreRender() verifies that a #pre_render callback for a render
  // array that is cacheable and …
  // - … is cached does NOT get called. (Also mock a render cache item.)
  // - … is not cached DOES get called.
  \Drupal::state()->set('bubbling_nested_pre_render_cached', FALSE);
  \Drupal::state()->set('bubbling_nested_pre_render_uncached', FALSE);
  $cacheability = new CacheableMetadata();
  $this->memoryCache
    ->set([
    'cached_nested',
  ], [
    '#markup' => 'Cached nested!',
    '#attached' => [],
    '#cache' => [
      'contexts' => [],
      'tags' => [],
    ],
  ], $cacheability, $cacheability);
  // Simulate the rendering of an entire response (i.e. a root call).
  $output = (string) $this->renderer
    ->renderRoot($test_element);
  // First, assert the render array is of the expected form.
  $this->assertEquals('Cache context!Cache tag!Asset!Placeholder!barstoolNested!Cached nested!', trim($output), 'Expected HTML generated.');
  $this->assertEquals([
    'child.cache_context',
  ], $test_element['#cache']['contexts'], 'Expected cache contexts found.');
  $this->assertEquals([
    'child:cache_tag',
  ], $test_element['#cache']['tags'], 'Expected cache tags found.');
  $expected_attached = [
    'drupalSettings' => [
      'foo' => 'bar',
    ],
    'placeholders' => [],
  ];
  $this->assertEquals($expected_attached, $test_element['#attached'], 'Expected attachments found.');
  // Second, assert that #pre_render callbacks are only executed if they don't
  // have a render cache hit (and hence a #pre_render callback for a render
  // cached item cannot bubble more metadata).
  $this->assertTrue(\Drupal::state()->get('bubbling_nested_pre_render_uncached'));
  $this->assertFalse(\Drupal::state()->get('bubbling_nested_pre_render_cached'));
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.