function RendererPlaceholdersTest::testRenderChildrenPlaceholdersDifferentArguments

Same name in other branches
  1. 9 core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php \Drupal\Tests\Core\Render\RendererPlaceholdersTest::testRenderChildrenPlaceholdersDifferentArguments()
  2. 10 core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php \Drupal\Tests\Core\Render\RendererPlaceholdersTest::testRenderChildrenPlaceholdersDifferentArguments()
  3. 11.x core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php \Drupal\Tests\Core\Render\RendererPlaceholdersTest::testRenderChildrenPlaceholdersDifferentArguments()

Create an element with a child and subchild. Each element has the same #lazy_builder callback, but with different contexts. They don't modify markup, only attach additional drupalSettings.

@covers ::render @covers ::doRender @covers \Drupal\Core\Render\RenderCache::get @covers ::replacePlaceholders

File

core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php, line 975

Class

RendererPlaceholdersTest
@coversDefaultClass \Drupal\Core\Render\Renderer @covers \Drupal\Core\Render\RenderCache @covers \Drupal\Core\Render\PlaceholderingRenderCache @group Render

Namespace

Drupal\Tests\Core\Render

Code

public function testRenderChildrenPlaceholdersDifferentArguments() {
    $this->setUpRequest();
    $this->setupMemoryCache();
    $this->cacheContextsManager
        ->expects($this->any())
        ->method('convertTokensToKeys')
        ->willReturnArgument(0);
    $this->controllerResolver
        ->expects($this->any())
        ->method('getControllerFromDefinition')
        ->willReturnArgument(0);
    $this->setupThemeManagerForDetails();
    $args_1 = [
        'foo',
        TRUE,
    ];
    $args_2 = [
        'bar',
        TRUE,
    ];
    $args_3 = [
        'baz',
        TRUE,
    ];
    $test_element = $this->generatePlaceholdersWithChildrenTestElement($args_1, $args_2, $args_3);
    $element = $test_element;
    $output = $this->renderer
        ->renderRoot($element);
    $expected_output = <<<HTML
<details>
  <summary>Parent</summary>
  <div class="details-wrapper"><details>
  <summary>Child</summary>
  <div class="details-wrapper">Subchild</div>
</details></div>
</details>
HTML;
    $this->assertSame($expected_output, (string) $output, 'Output is not overridden.');
    $this->assertTrue(isset($element['#printed']), 'No cache hit');
    $this->assertSame($expected_output, (string) $element['#markup'], '#markup is not overridden.');
    $expected_js_settings = [
        'foo' => 'bar',
        'dynamic_animal' => [
            $args_1[0] => TRUE,
            $args_2[0] => TRUE,
            $args_3[0] => TRUE,
        ],
    ];
    $this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the ones added by each placeholder #lazy_builder callback exist.');
    // GET request: validate cached data.
    $cached_element = $this->memoryCache
        ->get('simpletest:renderer:children_placeholders')->data;
    $expected_element = [
        '#attached' => [
            'drupalSettings' => [
                'foo' => 'bar',
            ],
            'placeholders' => [
                'parent-x-parent' => [
                    '#lazy_builder' => [
                        __NAMESPACE__ . '\\PlaceholdersTest::callback',
                        $args_1,
                    ],
                ],
                'child-x-child' => [
                    '#lazy_builder' => [
                        __NAMESPACE__ . '\\PlaceholdersTest::callback',
                        $args_2,
                    ],
                ],
                'subchild-x-subchild' => [
                    '#lazy_builder' => [
                        __NAMESPACE__ . '\\PlaceholdersTest::callback',
                        $args_3,
                    ],
                ],
            ],
        ],
        '#cache' => [
            'contexts' => [],
            'tags' => [],
            'max-age' => Cache::PERMANENT,
        ],
    ];
    $dom = Html::load($cached_element['#markup']);
    $xpath = new \DOMXPath($dom);
    $parent = $xpath->query('//details/summary[text()="Parent"]')->length;
    $child = $xpath->query('//details/div[@class="details-wrapper"]/details/summary[text()="Child"]')->length;
    $subchild = $xpath->query('//details/div[@class="details-wrapper"]/details/div[@class="details-wrapper" and text()="Subchild"]')->length;
    $this->assertTrue($parent && $child && $subchild, 'The correct data is cached: the stored #markup is not affected by placeholder #lazy_builder callbacks.');
    // Remove markup because it's compared above in the xpath.
    unset($cached_element['#markup']);
    $this->assertEquals($cached_element, $expected_element, 'The correct data is cached: the stored #attached properties are not affected by placeholder #lazy_builder callbacks.');
    // GET request: #cache enabled, cache hit.
    $element = $test_element;
    $output = $this->renderer
        ->renderRoot($element);
    $this->assertSame($expected_output, (string) $output, 'Output is not overridden.');
    $this->assertFalse(isset($element['#printed']), 'Cache hit');
    $this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the ones added by each placeholder #lazy_builder callback exist.');
    // Use the exact same element, but now unset #cache; ensure we get the same
    // result.
    unset($test_element['#cache']);
    $element = $test_element;
    $output = $this->renderer
        ->renderRoot($element);
    $this->assertSame($expected_output, (string) $output, 'Output is not overridden.');
    $this->assertSame($expected_output, (string) $element['#markup'], '#markup is not overridden.');
    $this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the ones added by each #lazy_builder callback exist.');
}

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