function RendererBubblingTest::testBubblingWithPrerender

Same name in other branches
  1. 8.9.x core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php \Drupal\Tests\Core\Render\RendererBubblingTest::testBubblingWithPrerender()
  2. 10 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 537

Class

RendererBubblingTest
@coversDefaultClass \Drupal\Core\Render\Renderer @group Render

Namespace

Drupal\Tests\Core\Render

Code

public function testBubblingWithPrerender($test_element) {
    $this->setUpRequest();
    $this->setupMemoryCache();
    // Mock the State service.
    $memory_state = new State(new KeyValueMemoryFactory());
    \Drupal::getContainer()->set('state', $memory_state);
    $this->controllerResolver
        ->expects($this->any())
        ->method('getControllerFromDefinition')
        ->willReturnArgument(0);
    // 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);
    $this->memoryCache
        ->set('cached_nested', [
        '#markup' => 'Cached nested!',
        '#attached' => [],
        '#cache' => [
            'contexts' => [],
            'tags' => [],
        ],
    ]);
    // Simulate the rendering of an entire response (i.e. a root call).
    $output = $this->renderer
        ->renderRoot($test_element);
    // First, assert the render array is of the expected form.
    $this->assertEquals('Cache context!Cache tag!Asset!Placeholder!barquxNested!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.