You are here

abstract class RendererTestBase in Drupal 9

Same name and namespace in other branches
  1. 8 core/tests/Drupal/Tests/Core/Render/RendererTestBase.php \Drupal\Tests\Core\Render\RendererTestBase

Base class for the actual unit tests testing \Drupal\Core\Render\Renderer.

Hierarchy

Expanded class hierarchy of RendererTestBase

1 file declares its use of RendererTestBase
HtmlTagTest.php in core/tests/Drupal/Tests/Core/Render/Element/HtmlTagTest.php

File

core/tests/Drupal/Tests/Core/Render/RendererTestBase.php, line 26
Contains \Drupal\Tests\Core\Render\RendererTestBase.

Namespace

Drupal\Tests\Core\Render
View source
abstract class RendererTestBase extends UnitTestCase {

  /**
   * The tested renderer.
   *
   * @var \Drupal\Core\Render\Renderer
   */
  protected $renderer;

  /**
   * The tested render cache.
   *
   * @var \Drupal\Core\Render\PlaceholderingRenderCache
   */
  protected $renderCache;

  /**
   * The tested placeholder generator.
   *
   * @var \Drupal\Core\Render\PlaceholderGenerator
   */
  protected $placeholderGenerator;

  /**
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  /**
   * @var \Drupal\Core\Cache\CacheFactoryInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $cacheFactory;

  /**
   * @var \Drupal\Core\Cache\Context\CacheContextsManager|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $cacheContexts;

  /**
   * The mocked controller resolver.
   *
   * @var \Drupal\Core\Controller\ControllerResolverInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $controllerResolver;

  /**
   * The mocked theme manager.
   *
   * @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $themeManager;

  /**
   * The mocked element info.
   *
   * @var \Drupal\Core\Render\ElementInfoManagerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $elementInfo;

  /**
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $memoryCache;

  /**
   * The simulated "current" user role, for use in tests with cache contexts.
   *
   * @var string
   */
  protected $currentUserRole;

  /**
   * The mocked renderer configuration.
   *
   * @var array
   */
  protected $rendererConfig = [
    'required_cache_contexts' => [
      'languages:language_interface',
      'theme',
    ],
    'auto_placeholder_conditions' => [
      'max-age' => 0,
      'contexts' => [
        'session',
        'user',
      ],
      'tags' => [
        'current-temperature',
      ],
    ],
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->controllerResolver = $this
      ->createMock('Drupal\\Core\\Controller\\ControllerResolverInterface');
    $this->themeManager = $this
      ->createMock('Drupal\\Core\\Theme\\ThemeManagerInterface');
    $this->elementInfo = $this
      ->createMock('Drupal\\Core\\Render\\ElementInfoManagerInterface');
    $this->elementInfo
      ->expects($this
      ->any())
      ->method('getInfo')
      ->willReturnCallback(function ($type) {
      switch ($type) {
        case 'details':
          $info = [
            '#theme_wrappers' => [
              'details',
            ],
          ];
          break;
        case 'link':
          $info = [
            '#theme' => 'link',
          ];
          break;
        default:
          $info = [];
      }
      $info['#defaults_loaded'] = TRUE;
      return $info;
    });
    $this->requestStack = new RequestStack();
    $request = new Request();
    $request->server
      ->set('REQUEST_TIME', $_SERVER['REQUEST_TIME']);
    $this->requestStack
      ->push($request);
    $this->cacheFactory = $this
      ->createMock('Drupal\\Core\\Cache\\CacheFactoryInterface');
    $this->cacheContextsManager = $this
      ->getMockBuilder('Drupal\\Core\\Cache\\Context\\CacheContextsManager')
      ->disableOriginalConstructor()
      ->getMock();
    $this->cacheContextsManager
      ->method('assertValidTokens')
      ->willReturn(TRUE);
    $current_user_role =& $this->currentUserRole;
    $this->cacheContextsManager
      ->expects($this
      ->any())
      ->method('convertTokensToKeys')
      ->willReturnCallback(function ($context_tokens) use (&$current_user_role) {
      $keys = [];
      foreach ($context_tokens as $context_id) {
        switch ($context_id) {
          case 'user.roles':
            $keys[] = 'r.' . $current_user_role;
            break;
          case 'languages:language_interface':
            $keys[] = 'en';
            break;
          case 'theme':
            $keys[] = 'stark';
            break;
          default:
            $keys[] = $context_id;
        }
      }
      return new ContextCacheKeys($keys, new CacheableMetadata());
    });
    $this->placeholderGenerator = new PlaceholderGenerator($this->rendererConfig);
    $this->renderCache = new PlaceholderingRenderCache($this->requestStack, $this->cacheFactory, $this->cacheContextsManager, $this->placeholderGenerator);
    $this->renderer = new Renderer($this->controllerResolver, $this->themeManager, $this->elementInfo, $this->placeholderGenerator, $this->renderCache, $this->requestStack, $this->rendererConfig);
    $container = new ContainerBuilder();
    $container
      ->set('cache_contexts_manager', $this->cacheContextsManager);
    $container
      ->set('render_cache', $this->renderCache);
    $container
      ->set('renderer', $this->renderer);
    \Drupal::setContainer($container);
  }

  /**
   * Generates a random context value for the placeholder tests.
   *
   * The #context array used by the placeholder #lazy_builder callback will
   * generally be used to provide metadata like entity IDs, field machine names,
   * paths, etc. for JavaScript replacement of content or assets. In this test,
   * the #lazy_builder callback PlaceholdersTest::callback() renders the context
   * inside test HTML, so using any random string would sometimes cause random
   * test failures because the test output would be unparseable. Instead, we
   * provide random tokens for replacement.
   *
   * @see PlaceholdersTest::callback()
   * @see https://www.drupal.org/node/2151609
   */
  protected function randomContextValue() {
    $tokens = [
      'llama',
      'alpaca',
      'camel',
      'moose',
      'elk',
    ];
    return $tokens[mt_rand(0, 4)];
  }

  /**
   * Sets up a render cache back-end that is asserted to be never used.
   */
  protected function setUpUnusedCache() {
    $this->cacheFactory
      ->expects($this
      ->never())
      ->method('get');
  }

  /**
   * Sets up a memory-based render cache back-end.
   */
  protected function setupMemoryCache() {
    $this->memoryCache = $this->memoryCache ?: new MemoryBackend();
    $this->cacheFactory
      ->expects($this
      ->atLeastOnce())
      ->method('get')
      ->with('render')
      ->willReturn($this->memoryCache);
  }

  /**
   * Sets up a request object on the request stack.
   *
   * @param string $method
   *   The HTTP method to use for the request. Defaults to 'GET'.
   */
  protected function setUpRequest($method = 'GET') {
    $request = Request::create('/', $method);

    // Ensure that the request time is set as expected.
    $request->server
      ->set('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
    $this->requestStack
      ->push($request);
  }

  /**
   * Asserts a render cache item.
   *
   * @param string $cid
   *   The expected cache ID.
   * @param mixed $data
   *   The expected data for that cache ID.
   * @param string $bin
   *   The expected cache bin.
   */
  protected function assertRenderCacheItem($cid, $data, $bin = 'render') {
    $cache_backend = $this->cacheFactory
      ->get($bin);
    $cached = $cache_backend
      ->get($cid);
    $this
      ->assertNotFalse($cached, sprintf('Expected cache item "%s" exists.', $cid));
    if ($cached !== FALSE) {
      $this
        ->assertEqualsCanonicalizing(array_keys($data), array_keys($cached->data), 'The cache item contains the same parent array keys.');
      foreach ($data as $key => $value) {

        // We do not want to assert on the order of cacheability information.
        // @see https://www.drupal.org/project/drupal/issues/3225328
        if ($key === '#cache') {
          $this
            ->assertEqualsCanonicalizing($value, $cached->data[$key], sprintf('Cache item "%s" has the expected data.', $cid));
        }
        else {
          $this
            ->assertEquals($value, $cached->data[$key], sprintf('Cache item "%s" has the expected data.', $cid));
        }
      }
      $this
        ->assertEqualsCanonicalizing(Cache::mergeTags($data['#cache']['tags'], [
        'rendered',
      ]), $cached->tags, "The cache item's cache tags also has the 'rendered' cache tag.");
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
RendererTestBase::$cacheContexts protected property
RendererTestBase::$cacheFactory protected property
RendererTestBase::$controllerResolver protected property The mocked controller resolver.
RendererTestBase::$currentUserRole protected property The simulated "current" user role, for use in tests with cache contexts.
RendererTestBase::$elementInfo protected property The mocked element info.
RendererTestBase::$memoryCache protected property
RendererTestBase::$placeholderGenerator protected property The tested placeholder generator. 1
RendererTestBase::$renderCache protected property The tested render cache.
RendererTestBase::$renderer protected property The tested renderer.
RendererTestBase::$rendererConfig protected property The mocked renderer configuration.
RendererTestBase::$requestStack protected property
RendererTestBase::$themeManager protected property The mocked theme manager.
RendererTestBase::assertRenderCacheItem protected function Asserts a render cache item.
RendererTestBase::randomContextValue protected function Generates a random context value for the placeholder tests.
RendererTestBase::setUp protected function Overrides UnitTestCase::setUp 3
RendererTestBase::setupMemoryCache protected function Sets up a memory-based render cache back-end.
RendererTestBase::setUpRequest protected function Sets up a request object on the request stack.
RendererTestBase::setUpUnusedCache protected function Sets up a render cache back-end that is asserted to be never used.
UnitTestCase::$randomGenerator protected property The random generator.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::assertArrayEquals Deprecated protected function Asserts if two arrays are equal by sorting them first.
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getRandomGenerator protected function Gets the random generator for the utility methods.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::randomMachineName public function Generates a unique random string containing letters and numbers.
UnitTestCase::setUpBeforeClass public static function