You are here

public function PageBlockDisplayVariantTest::testBuild in Page Manager 8.4

Same name and namespace in other branches
  1. 8 tests/src/Unit/PageBlockDisplayVariantTest.php \Drupal\Tests\page_manager\Unit\PageBlockDisplayVariantTest::testBuild()

Tests the build() method when blocks can be cached.

@covers ::build @covers ::buildRegions @covers ::buildBlock

File

tests/src/Unit/PageBlockDisplayVariantTest.php, line 93

Class

PageBlockDisplayVariantTest
Tests the block variant plugin.

Namespace

Drupal\Tests\page_manager\Unit

Code

public function testBuild() {
  $container = new ContainerBuilder();
  $cache_contexts = $this
    ->prophesize(CacheContextsManager::class);
  $container
    ->set('cache_contexts_manager', $cache_contexts
    ->reveal());
  \Drupal::setContainer($container);
  $account = $this
    ->prophesize(AccountInterface::class);

  // Define one block that allows access, access varies by permissions.
  $cache_contexts
    ->assertValidTokens([
    'user.permissions',
  ])
    ->willReturn(TRUE);
  $block1 = $this
    ->prophesize(BlockPluginInterface::class);
  $block1
    ->access($account, TRUE)
    ->willReturn(AccessResult::allowed()
    ->cachePerPermissions());
  $block1
    ->getConfiguration()
    ->willReturn([
    'label' => 'Block label',
  ]);
  $block1
    ->getPluginId()
    ->willReturn('block_plugin_id');
  $block1
    ->getBaseId()
    ->willReturn('block_base_plugin_id');
  $block1
    ->getDerivativeId()
    ->willReturn('block_derivative_plugin_id');
  $block1
    ->getCacheTags()
    ->willReturn([
    'block_plugin1:block_plugin_id',
  ]);
  $block1
    ->getCacheMaxAge()
    ->willReturn(3600);
  $block1
    ->getCacheContexts()
    ->willReturn([
    'url',
  ]);

  // Define another block that doesn't allow access, varies by user.
  $cache_contexts
    ->assertValidTokens([
    'user',
  ])
    ->willReturn(TRUE);
  $block2 = $this
    ->prophesize()
    ->willImplement(ContextAwarePluginInterface::class)
    ->willImplement(BlockPluginInterface::class);
  $block2
    ->access($account, TRUE)
    ->willReturn(AccessResult::forbidden()
    ->cachePerUser());
  $block2
    ->getConfiguration()
    ->willReturn([]);
  $block2
    ->getPluginId()
    ->willReturn('block_plugin_id');
  $block2
    ->getBaseId()
    ->willReturn('block_base_plugin_id');
  $block2
    ->getDerivativeId()
    ->willReturn('block_derivative_plugin_id');

  // The block is not shown, so cacheability metadata is not collected.
  $block2
    ->getCacheContexts()
    ->shouldNotBeCalled();
  $block2
    ->getCacheMaxAge()
    ->shouldNotBeCalled();
  $block2
    ->getCacheTags()
    ->shouldNotBeCalled();
  $blocks = [
    'top' => [
      'block1' => $block1
        ->reveal(),
      'block2' => $block2
        ->reveal(),
    ],
  ];
  $block_collection = $this
    ->getMockBuilder(BlockPluginCollection::class)
    ->disableOriginalConstructor()
    ->getMock();
  $block_collection
    ->expects($this
    ->once())
    ->method('getAllByRegion')
    ->willReturn($blocks);
  $context_handler = $this
    ->prophesize(ContextHandlerInterface::class);
  $context_handler
    ->applyContextMapping($block2
    ->reveal(), [])
    ->shouldBeCalledTimes(1);
  $module_handler = $this
    ->prophesize(ModuleHandlerInterface::class);
  $module_handler
    ->alter();
  $uuid_generator = $this
    ->prophesize(UuidInterface::class);
  $page_title = 'Page title';
  $token = $this
    ->getMockBuilder(Token::class)
    ->disableOriginalConstructor()
    ->getMock();
  $block_manager = $this
    ->prophesize(BlockManager::class);
  $condition_manager = $this
    ->prophesize(ConditionManager::class);
  $variant_plugin = $this
    ->getMockBuilder(PageBlockDisplayVariant::class)
    ->setConstructorArgs([
    [
      'page_title' => $page_title,
      'uuid' => 'UUID',
    ],
    'test',
    [],
    $context_handler
      ->reveal(),
    $account
      ->reveal(),
    $uuid_generator
      ->reveal(),
    $token,
    $block_manager
      ->reveal(),
    $condition_manager
      ->reveal(),
    $module_handler
      ->reveal(),
  ])
    ->setMethods([
    'renderPageTitle',
  ])
    ->getMock();
  $property = new \ReflectionProperty($variant_plugin, 'blockPluginCollection');
  $property
    ->setAccessible(TRUE);
  $property
    ->setValue($variant_plugin, $block_collection);
  $page = $this
    ->prophesize(PageInterface::class);
  $page
    ->id()
    ->willReturn('page_id');
  $variant_plugin
    ->expects($this
    ->once())
    ->method('renderPageTitle')
    ->with($page_title)
    ->willReturn($page_title);
  $expected_cache_block1 = [
    'keys' => [
      'page_manager_block_display',
      'UUID',
      'block',
      'block1',
    ],
    'tags' => [
      'block_plugin1:block_plugin_id',
    ],
    'contexts' => [
      'url',
    ],
    'max-age' => 3600,
  ];
  $cache_contexts
    ->assertValidTokens([
    'user.permissions',
    'url',
  ])
    ->willReturn(TRUE);

  // The page cacheability metadata contains the access cacheability metadata
  // of accessible and non-accessible blocks. Additionally, the cacheability
  // metadata of accessible blocks is merged to avoid cache redirects when
  // possible.
  $expected_cache_page = [
    'keys' => [
      'page_manager_block_display',
      'UUID',
    ],
    'contexts' => [
      'url',
      'user',
      'user.permissions',
    ],
    'tags' => [
      'block_plugin1:block_plugin_id',
    ],
    'max-age' => 3600,
  ];
  $cache_contexts
    ->assertValidTokens([
    'url',
    'user.permissions',
    'user',
  ])
    ->willReturn(TRUE);

  // Build the variant and ensure that pre_render is set only for the first
  // block.
  $build = $variant_plugin
    ->build();
  $build = $variant_plugin
    ->buildRegions($build);
  $this
    ->assertSame([
    $variant_plugin,
    'buildBlock',
  ], $build['top']['block1']['#pre_render'][0]);
  $this
    ->assertTrue(empty($build['top']['block2']));
  $this
    ->assertSame($expected_cache_block1, $build['top']['block1']['#cache']);
  $this
    ->assertSame($expected_cache_page, $build['#cache']);

  // Ensure that building the block returns the correct markup.
  $block1
    ->build()
    ->willReturn([
    '#markup' => 'block1_build_value',
  ]);
  $block1_build = $variant_plugin
    ->buildBlock($build['top']['block1']);
  $this
    ->assertSame([
    '#markup' => 'block1_build_value',
  ], $block1_build['content']);
}