function RendererBubblingTest::testBubblingWithPrerender

Same name 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. 10 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 @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.