You are here

public function RendererBubblingTest::providerTestContextBubblingEdgeCases in Drupal 8

Same name and namespace in other branches
  1. 9 core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php \Drupal\Tests\Core\Render\RendererBubblingTest::providerTestContextBubblingEdgeCases()
  2. 10 core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php \Drupal\Tests\Core\Render\RendererBubblingTest::providerTestContextBubblingEdgeCases()

File

core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php, line 151
Contains \Drupal\Tests\Core\Render\RendererBubblingTest.

Class

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

Namespace

Drupal\Tests\Core\Render

Code

public function providerTestContextBubblingEdgeCases() {
  $data = [];

  // Cache contexts of inaccessible children aren't bubbled (because those
  // children are not rendered at all).
  $test_element = [
    '#cache' => [
      'keys' => [
        'parent',
      ],
      'contexts' => [],
    ],
    '#markup' => 'parent',
    'child' => [
      '#access' => FALSE,
      '#cache' => [
        'contexts' => [
          'foo',
        ],
      ],
    ],
  ];
  $expected_cache_items = [
    'parent' => [
      '#attached' => [],
      '#cache' => [
        'contexts' => [],
        'tags' => [],
        'max-age' => Cache::PERMANENT,
      ],
      '#markup' => 'parent',
    ],
  ];
  $data[] = [
    $test_element,
    [],
    $expected_cache_items,
  ];

  // Assert cache contexts are sorted when they are used to generate a CID.
  // (Necessary to ensure that different render arrays where the same keys +
  // set of contexts are present point to the same cache item. Regardless of
  // the contexts' order. A sad necessity because PHP doesn't have sets.)
  $test_element = [
    '#cache' => [
      'keys' => [
        'set_test',
      ],
      'contexts' => [],
    ],
  ];
  $expected_cache_items = [
    'set_test:bar:baz:foo' => [
      '#attached' => [],
      '#cache' => [
        'contexts' => [],
        'tags' => [],
        'max-age' => Cache::PERMANENT,
      ],
      '#markup' => '',
    ],
  ];
  $context_orders = [
    [
      'foo',
      'bar',
      'baz',
    ],
    [
      'foo',
      'baz',
      'bar',
    ],
    [
      'bar',
      'foo',
      'baz',
    ],
    [
      'bar',
      'baz',
      'foo',
    ],
    [
      'baz',
      'foo',
      'bar',
    ],
    [
      'baz',
      'bar',
      'foo',
    ],
  ];
  foreach ($context_orders as $context_order) {
    $test_element['#cache']['contexts'] = $context_order;
    sort($context_order);
    $expected_cache_items['set_test:bar:baz:foo']['#cache']['contexts'] = $context_order;
    $data[] = [
      $test_element,
      $context_order,
      $expected_cache_items,
    ];
  }

  // A parent with a certain set of cache contexts is unaffected by a child
  // that has a subset of those contexts.
  $test_element = [
    '#cache' => [
      'keys' => [
        'parent',
      ],
      'contexts' => [
        'foo',
        'bar',
        'baz',
      ],
    ],
    '#markup' => 'parent',
    'child' => [
      '#cache' => [
        'contexts' => [
          'foo',
          'baz',
        ],
        'max-age' => 3600,
      ],
    ],
  ];
  $expected_cache_items = [
    'parent:bar:baz:foo' => [
      '#attached' => [],
      '#cache' => [
        'contexts' => [
          'bar',
          'baz',
          'foo',
        ],
        'tags' => [],
        'max-age' => 3600,
      ],
      '#markup' => 'parent',
    ],
  ];
  $data[] = [
    $test_element,
    [
      'bar',
      'baz',
      'foo',
    ],
    $expected_cache_items,
  ];

  // A parent with a certain set of cache contexts that is a subset of the
  // cache contexts of a child gets a redirecting cache item for the cache ID
  // created pre-bubbling (without the child's additional cache contexts). It
  // points to a cache item with a post-bubbling cache ID (i.e. with the
  // child's additional cache contexts).
  // Furthermore, the redirecting cache item also includes the children's
  // cache tags, since changes in the children may cause those children to get
  // different cache contexts and therefore cause different cache contexts to
  // be stored in the redirecting cache item.
  $test_element = [
    '#cache' => [
      'keys' => [
        'parent',
      ],
      'contexts' => [
        'foo',
      ],
      'tags' => [
        'yar',
        'har',
      ],
    ],
    '#markup' => 'parent',
    'child' => [
      '#cache' => [
        'contexts' => [
          'bar',
        ],
        'tags' => [
          'fiddle',
          'dee',
        ],
      ],
      '#markup' => '',
    ],
  ];
  $expected_cache_items = [
    'parent:foo' => [
      '#cache_redirect' => TRUE,
      '#cache' => [
        // The keys + contexts this redirects to.
        'keys' => [
          'parent',
        ],
        'contexts' => [
          'bar',
          'foo',
        ],
        'tags' => [
          'dee',
          'fiddle',
          'har',
          'yar',
        ],
        'bin' => 'render',
        'max-age' => Cache::PERMANENT,
      ],
    ],
    'parent:bar:foo' => [
      '#attached' => [],
      '#cache' => [
        'contexts' => [
          'bar',
          'foo',
        ],
        'tags' => [
          'dee',
          'fiddle',
          'har',
          'yar',
        ],
        'max-age' => Cache::PERMANENT,
      ],
      '#markup' => 'parent',
    ],
  ];
  $data[] = [
    $test_element,
    [
      'bar',
      'foo',
    ],
    $expected_cache_items,
  ];

  // Ensure that bubbleable metadata has been collected from children and set
  // correctly to the main level of the render array. That ensures that correct
  // bubbleable metadata exists if render array gets rendered multiple times.
  $test_element = [
    '#cache' => [
      'keys' => [
        'parent',
      ],
      'tags' => [
        'yar',
        'har',
      ],
    ],
    '#markup' => 'parent',
    'child' => [
      '#render_children' => TRUE,
      'subchild' => [
        '#cache' => [
          'contexts' => [
            'foo',
          ],
          'tags' => [
            'fiddle',
            'dee',
          ],
        ],
        '#attached' => [
          'library' => [
            'foo/bar',
          ],
        ],
        '#markup' => '',
      ],
    ],
  ];
  $expected_cache_items = [
    'parent:foo' => [
      '#attached' => [
        'library' => [
          'foo/bar',
        ],
      ],
      '#cache' => [
        'contexts' => [
          'foo',
        ],
        'tags' => [
          'dee',
          'fiddle',
          'har',
          'yar',
        ],
        'max-age' => Cache::PERMANENT,
      ],
      '#markup' => 'parent',
    ],
  ];
  $data[] = [
    $test_element,
    [
      'foo',
    ],
    $expected_cache_items,
  ];
  return $data;
}