You are here

public function MenuLinkTreeTest::providerTestBuildCacheability in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php \Drupal\Tests\system\Unit\Menu\MenuLinkTreeTest::providerTestBuildCacheability()

Provides the test cases to test for ::testBuildCacheability().

As explained in the documentation for ::testBuildCacheability(), this generates 1 + (3 * 2 * 3) = 19 test cases.

See also

testBuildCacheability

File

core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php, line 115

Class

MenuLinkTreeTest
@coversDefaultClass \Drupal\Core\Menu\MenuLinkTree @group Menu

Namespace

Drupal\Tests\system\Unit\Menu

Code

public function providerTestBuildCacheability() {
  $base_expected_build_empty = [
    '#cache' => [
      'contexts' => [],
      'tags' => [],
      'max-age' => Cache::PERMANENT,
    ],
  ];
  $base_expected_build = [
    '#cache' => [
      'contexts' => [],
      'tags' => [
        'config:system.menu.mock',
      ],
      'max-age' => Cache::PERMANENT,
    ],
    '#sorted' => TRUE,
    '#menu_name' => 'mock',
    '#theme' => 'menu__mock',
    '#items' => [],
  ];
  $get_built_element = function (MenuLinkTreeElement $element) {
    $return = [
      'attributes' => new Attribute(),
      'title' => $element->link
        ->getTitle(),
      'url' => new Url($element->link
        ->getRouteName(), $element->link
        ->getRouteParameters(), [
        'set_active_class' => TRUE,
      ]),
      'below' => [],
      'original_link' => $element->link,
      'is_expanded' => FALSE,
      'is_collapsed' => FALSE,
      'in_active_trail' => FALSE,
    ];
    if ($element->hasChildren && !empty($element->subtree)) {
      $return['is_expanded'] = TRUE;
    }
    elseif ($element->hasChildren) {
      $return['is_collapsed'] = TRUE;
    }
    if ($element->inActiveTrail) {
      $return['in_active_trail'] = TRUE;
    }
    return $return;
  };

  // The three access scenarios described in this method's documentation.
  $access_scenarios = [
    [
      NULL,
      [],
    ],
    [
      AccessResult::allowed(),
      [
        'access:allowed',
      ],
    ],
    [
      AccessResult::neutral(),
      [
        'access:neutral',
      ],
    ],
  ];

  // The two links scenarios described in this method's documentation.
  $cache_defaults = [
    'cache_max_age' => Cache::PERMANENT,
    'cache_tags' => [],
  ];
  $links_scenarios = [
    [
      MenuLinkMock::create([
        'id' => 'test.example1',
        'route_name' => 'example1',
        'title' => 'Example 1',
      ]),
      MenuLinkMock::create([
        'id' => 'test.example2',
        'route_name' => 'example1',
        'title' => 'Example 2',
        'metadata' => [
          'cache_contexts' => [
            'llama',
          ],
        ] + $cache_defaults,
      ]),
    ],
    [
      MenuLinkMock::create([
        'id' => 'test.example1',
        'route_name' => 'example1',
        'title' => 'Example 1',
        'metadata' => [
          'cache_contexts' => [
            'foo',
          ],
        ] + $cache_defaults,
      ]),
      MenuLinkMock::create([
        'id' => 'test.example2',
        'route_name' => 'example1',
        'title' => 'Example 2',
        'metadata' => [
          'cache_contexts' => [
            'bar',
          ],
        ] + $cache_defaults,
      ]),
    ],
  ];
  $data = [];

  // Empty tree.
  $data[] = [
    'description' => 'Empty tree.',
    'tree' => [],
    'expected_build' => $base_expected_build_empty,
    'access' => NULL,
    'access_cache_contexts' => [],
  ];
  for ($i = 0; $i < count($access_scenarios); $i++) {
    list($access, $access_cache_contexts) = $access_scenarios[$i];
    for ($j = 0; $j < count($links_scenarios); $j++) {
      $links = $links_scenarios[$j];

      // Single-element tree.
      $tree = [
        new MenuLinkTreeElement($links[0], FALSE, 0, FALSE, []),
      ];
      $tree[0]->access = $access;
      if ($access === NULL || $access
        ->isAllowed()) {
        $expected_build = $base_expected_build;
        $expected_build['#items']['test.example1'] = $get_built_element($tree[0]);
      }
      else {
        $expected_build = $base_expected_build_empty;
      }
      $expected_build['#cache']['contexts'] = array_merge($expected_build['#cache']['contexts'], $access_cache_contexts, $links[0]
        ->getCacheContexts());
      $data[] = [
        'description' => "Single-item tree; access={$i}; link={$j}.",
        'tree' => $tree,
        'expected_build' => $expected_build,
        'access' => $access,
        'access_cache_contexts' => $access_cache_contexts,
      ];

      // Single-level tree.
      $tree = [
        new MenuLinkTreeElement($links[0], FALSE, 0, FALSE, []),
        new MenuLinkTreeElement($links[1], FALSE, 0, FALSE, []),
      ];
      $tree[0]->access = $access;
      $expected_build = $base_expected_build;
      if ($access === NULL || $access
        ->isAllowed()) {
        $expected_build['#items']['test.example1'] = $get_built_element($tree[0]);
      }
      $expected_build['#items']['test.example2'] = $get_built_element($tree[1]);
      $expected_build['#cache']['contexts'] = array_merge($expected_build['#cache']['contexts'], $access_cache_contexts, $links[0]
        ->getCacheContexts(), $links[1]
        ->getCacheContexts());
      $data[] = [
        'description' => "Single-level tree; access={$i}; link={$j}.",
        'tree' => $tree,
        'expected_build' => $expected_build,
        'access' => $access,
        'access_cache_contexts' => $access_cache_contexts,
      ];

      // Multi-level tree.
      $multi_level_root_a = MenuLinkMock::create([
        'id' => 'test.root_a',
        'route_name' => 'root_a',
        'title' => 'Root A',
      ]);
      $multi_level_root_b = MenuLinkMock::create([
        'id' => 'test.root_b',
        'route_name' => 'root_b',
        'title' => 'Root B',
      ]);
      $multi_level_parent_c = MenuLinkMock::create([
        'id' => 'test.parent_c',
        'route_name' => 'parent_c',
        'title' => 'Parent C',
      ]);
      $tree = [
        new MenuLinkTreeElement($multi_level_root_a, TRUE, 0, FALSE, [
          new MenuLinkTreeElement($multi_level_parent_c, TRUE, 0, FALSE, [
            new MenuLinkTreeElement($links[0], FALSE, 0, FALSE, []),
          ]),
        ]),
        new MenuLinkTreeElement($multi_level_root_b, TRUE, 0, FALSE, [
          new MenuLinkTreeElement($links[1], FALSE, 1, FALSE, []),
        ]),
      ];
      $tree[0]->subtree[0]->subtree[0]->access = $access;
      $expected_build = $base_expected_build;
      $expected_build['#items']['test.root_a'] = $get_built_element($tree[0]);
      $expected_build['#items']['test.root_a']['below']['test.parent_c'] = $get_built_element($tree[0]->subtree[0]);
      if ($access === NULL || $access
        ->isAllowed()) {
        $expected_build['#items']['test.root_a']['below']['test.parent_c']['below']['test.example1'] = $get_built_element($tree[0]->subtree[0]->subtree[0]);
      }
      $expected_build['#items']['test.root_b'] = $get_built_element($tree[1]);
      $expected_build['#items']['test.root_b']['below']['test.example2'] = $get_built_element($tree[1]->subtree[0]);
      $expected_build['#cache']['contexts'] = array_merge($expected_build['#cache']['contexts'], $access_cache_contexts, $links[0]
        ->getCacheContexts(), $links[1]
        ->getCacheContexts());
      $data[] = [
        'description' => "Multi-level tree; access={$i}; link={$j}.",
        'tree' => $tree,
        'expected_build' => $expected_build,
        'access' => $access,
        'access_cache_contexts' => $access_cache_contexts,
      ];
    }
  }
  return $data;
}