group_content_menu-8.x-1.0-rc3/tests/src/Functional/GroupContentMenuTest.php

tests/src/Functional/GroupContentMenuTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\group_content_menu\Functional;

use Drupal\Core\State\StateInterface;
use Drupal\Core\Url;
use Drupal\group\Entity\GroupInterface;
use Drupal\group\PermissionScopeInterface;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\group\Functional\GroupBrowserTestBase;
use Drupal\Tests\language\Traits\LanguageTestTrait;
use Drupal\user\Entity\User;
use Drupal\user\RoleInterface;
use Drupal\user\UserInterface;

/**
 * Test description.
 *
 * @group group_content_menu
 */
class GroupContentMenuTest extends GroupBrowserTestBase {

  use LanguageTestTrait;

  /**
   * State key to get/set before/after adding a custom theme hook suggestion.
   *
   * The state value identified by this key serves as an oracle to determine if
   * the the theme_hook_suggestion block configuration option is working as
   * designed.
   */
  public const THEME_SUGGESTION_TEST_STATE_KEY = 'group_content_menu_theme_hook_suggestion_called_key';

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'block',
    'group_content_menu',
    'group_content_menu_theme_hook_suggestion_test',
    'gnode',
    'menu_ui',
    'node',
    'views',
  ];

  /**
   * Menu ID.
   *
   * @var string
   */
  protected $menuId;

  /**
   * Group type generated in setUp.
   *
   * @var \Drupal\group\Entity\GroupType
   */
  protected $groupType;

  /**
   * Member role for $groupType.
   *
   * @var \Drupal\group\Entity\GroupRole
   */
  protected $memberRole;

  /**
   * Admin role for $groupType.
   *
   * @var \Drupal\group\Entity\GroupRole
   */
  protected $adminRole;

  /**
   * Outsider (non-member authenticated) role for $groupType.
   *
   * @var \Drupal\group\Entity\GroupRole
   */
  protected $outsiderRole;

  /**
   * Anonymous role for $groupType.
   *
   * @var \Drupal\group\Entity\GroupRole
   */
  protected $anonymousRole;

  /**
   * The Drupal state service.
   */
  protected StateInterface $state;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->setUpAccount();

    $this->state = $this->container->get('state');

    $this->menuId = strtolower($this->randomMachineName());

    // Create a basic page content type with a default menu.
    $type = $this->drupalCreateContentType([
      'type' => 'page',
      'name' => 'Basic page',
      'display_submitted' => FALSE,
    ]);
    $type->setThirdPartySetting('menu_ui', 'available_menus', ['main']);
    $type->save();
    // Create an article content type, without any default menu.
    $type = $this->drupalCreateContentType([
      'type' => 'article',
      'name' => 'Article',
      'display_submitted' => FALSE,
    ]);
    $type->setThirdPartySetting('menu_ui', 'available_menus', []);
    $type->save();

    $this->groupType = $this->createGroupType();
    // Add group permissions.
    $this->memberRole = $this->createGroupRole([
      'group_type' => $this->groupType->id(),
      'scope' => PermissionScopeInterface::INSIDER_ID,
      'global_role' => RoleInterface::AUTHENTICATED_ID,
      'permissions' => [
        'view group',
      ],
    ]);
    $this->adminRole = $this->createGroupRole([
      'group_type' => $this->groupType->id(),
      'scope' => PermissionScopeInterface::INDIVIDUAL_ID,
      'global_role' => NULL,
      'admin' => TRUE,
    ]);
    $this->outsiderRole = $this->createGroupRole([
      'group_type' => $this->groupType->id(),
      'scope' => PermissionScopeInterface::OUTSIDER_ID,
      'global_role' => RoleInterface::AUTHENTICATED_ID,
      'permissions' => [
        'view group',
      ],
    ]);
    $this->anonymousRole = $this->createGroupRole([
      'group_type' => $this->groupType->id(),
      'scope' => PermissionScopeInterface::OUTSIDER_ID,
      'global_role' => RoleInterface::ANONYMOUS_ID,
      'permissions' => [
        'view group',
      ],
    ]);

    // Enable the gnode content plugin for basic page and article.
    $this->entityTypeManager->getStorage('group_relationship_type')
      ->createFromPlugin($this->groupType, 'group_node:page')->save();
    $this->entityTypeManager->getStorage('group_relationship_type')
      ->createFromPlugin($this->groupType, 'group_node:article')->save();
  }

  /**
   * Test creation of a group content menu with group nodes.
   */
  public function testNodeGroupContentMenu(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    $group = $this->createGroup();
    $group_name = $group->label();
    $group_path = $group->toUrl()->toString();
    $this->createAndPlaceGroupMenu();
    $this->enableGroupMenuPlugin();

    // Verify the menu settings render even when no group menu has been created.
    $this->drupalGet($group_path . '/content/create/group_node:page');
    $assert->pageTextContains('Menu settings');
    $assert->pageTextContains('Parent link');
    $page->fillField('title[0][value]', 'Group node');
    $page->pressButton('Save');
    $this->drupalGet('/node/1/edit');
    $assert->statusCodeEquals(200);

    // Verify the menu settings do not display if no menus are available.
    $this->drupalGet($group_path . '/content/create/group_node:article');
    $assert->pageTextNotContains('Menu settings');

    // Create new group content menu.
    $this->drupalGet($group_path . '/menu/add');
    $new_menu_label = $this->randomString();
    $page->fillField('label[0][value]', $new_menu_label);
    $page->pressButton('Save');

    // Only one group content menu instance is created.
    $this->drupalGet($group_path . '/content');
    $assert->pageTextContainsOnce($new_menu_label);

    // Verify menu settings render when a group menu has been created.
    $this->drupalGet($group_path . '/content/create/group_node:page');
    $assert->pageTextContains('Menu settings');
    $assert->pageTextContains('Parent link');
    $page->checkField('menu[enabled]');
    $assert->optionExists('menu[menu_parent]', "<$new_menu_label ($group_name)>");
    $assert->optionExists('menu[menu_parent]', '<Main navigation>');
    $page->fillField('title[0][value]', 'Group node');
    $page->pressButton('Save');
    $this->drupalGet('/node/2/edit');
    $assert->statusCodeEquals(200);

    // Verify the menu settings display, even if no default menu selected.
    $this->drupalGet($group_path . '/content/create/group_node:article');
    $assert->pageTextContains('Menu settings');
    $assert->pageTextContains('Parent link');
    $assert->optionNotExists('menu[menu_parent]', 'Main navigation');
  }

  /**
   * Test creation of a group content menu.
   */
  public function testCreateGroupContentMenu(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    $this->createAndPlaceGroupMenu();
    $this->enableGroupMenuPlugin([
      'auto_create_group_menu' => TRUE,
      'auto_create_home_link' => TRUE,
      'auto_create_home_link_title' => 'Group home page',
    ]);
    $group = $this->createGroup();

    // Home link is editable.
    $this->drupalGet('/group/' . $group->id() . '/menu/1/link/1');
    $assert->statusCodeEquals(200);
    $page->pressButton('Save');
    $assert->pageTextContains('The menu link has been saved.');
    $assert->addressEquals('/group/' . $group->id() . '/menu/1/edit');

    // Add menu links to the newly created menu and render the menu.
    $this->drupalGet('/group/' . $group->id() . '/menu/1/edit');
    $assert->statusCodeEquals(200);
    $this->drupalGet('/group/' . $group->id() . '/menu/1/add-link');
    $assert->statusCodeEquals(200);
    // Add a link.
    $link_title = $this->randomString();
    $page->fillField('title[0][value]', $link_title);
    $page->fillField('link[0][uri]', '<front>');
    $page->pressButton('Save');
    // Edit the link.
    $this->drupalGet('/group/' . $group->id() . '/menu/1/link/2');
    $page->selectFieldOption('menu_parent', '-- Group home page');
    $page->pressButton('Save');
    $assert->pageTextContains('The menu link has been saved. ');
    $assert->linkExists($link_title);
    $assert->statusCodeEquals(200);

    // Delete the link.
    $this->drupalGet('/group/' . $group->id() . '/menu/1/link/2/delete');
    $page->pressButton('Delete');
    $assert->pageTextContains("The menu link $link_title has been deleted.");
    $assert->addressEquals('/group/' . $group->id() . '/menu/1/edit');

    // Delete menu.
    $this->drupalGet('/group/' . $group->id() . '/menu/1/delete');
    $page->pressButton('Delete');
    $assert->pageTextContains('There are no group content menu entities yet');

    // Re-add menu.
    $this->drupalGet(sprintf('/group/' . $group->id() . '/content/create/group_content_menu:%s', $this->menuId));
    $menu_title = $this->randomString();
    $page->fillField('label[0][value]', $menu_title);
    $page->pressButton('Save');
    $assert->pageTextContains("New group menu $menu_title has been created.");
  }

  /**
   * Test adding the group content menu item manually.
   */
  public function testAddMenuManually(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    $this->createAndPlaceGroupMenu();
    $this->enableGroupMenuPlugin();
    $this->createGroup();

    // Create new group content menu.
    $this->drupalGet('/group/1/menu/add');
    $menu_label = $this->randomString();
    $page->fillField('label[0][value]', $menu_label);
    $page->pressButton('Save');

    // Only one group content menu instance is created.
    $this->drupalGet('/group/1/content');
    $assert->pageTextContainsOnce($menu_label);
  }

  /**
   * Test creation of a group content menu with multiple menu types available.
   */
  public function testMultipleMenus(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    // Generate Group Menu One content menu type.
    $this->drupalGet('admin/structure/group_content_menu_types/add');
    $page->fillField('label', 'Group Menu One');
    $page->fillField('id', 'group_menu_one');
    $page->pressButton('Save');
    $assert->statusCodeEquals(200);
    $assert->pageTextContains('The group menu type Group Menu One has been added.');

    // Generate Group Menu Two content menu type.
    $this->drupalGet('admin/structure/group_content_menu_types/add');
    $page->fillField('label', 'Group Menu Two');
    $page->fillField('id', 'group_menu_two');
    $page->pressButton('Save');
    $assert->statusCodeEquals(200);
    $assert->pageTextContains('The group menu type Group Menu Two has been added.');

    // Enable the group content plugins for the default group type.
    $this->drupalGet('/admin/group/content/install/' . $this->groupType->id() . '/group_content_menu:group_menu_one');
    $page->pressButton('Install plugin');
    $assert->pageTextContains('The content plugin was installed on the group type. ');
    $this->drupalGet('/admin/group/content/install/' . $this->groupType->id() . '/group_content_menu:group_menu_two');
    $page->pressButton('Install plugin');
    $assert->pageTextContains('The content plugin was installed on the group type.');

    $this->container->get('group_relation_type.manager')->clearCachedDefinitions();
    $this->createGroup();

    // Create a group content menu.
    $this->drupalGet('group/1/menu/add');
    $page->clickLink('Group menu (Group Menu Two)');
    $assert->statusCodeEquals(200);
    $menu_title = $this->randomString();
    $page->fillField('label[0][value]', $menu_title);
    $page->pressButton('Save');
    $assert->pageTextContains("New group menu $menu_title has been created.");
  }

  /**
   * Test the custom theme hook suggestion block configuration option.
   */
  public function testCustomThemeHookSuggestion(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    $group_menu_block_id = $this->createAndPlaceGroupMenu();
    $this->enableGroupMenuPlugin([
      'auto_create_group_menu' => TRUE,
      'auto_create_home_link' => TRUE,
      'auto_create_home_link_title' => 'Group home page',
    ]);
    $this->createGroup();

    // Add a link.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_top_level = $this->randomString(8);
    $page->fillField('title[0][value]', $link_top_level);
    $page->fillField('link[0][uri]', 'http://example.com');
    $page->pressButton('Save');

    $this->drupalGet('/group/1');
    $assert->linkExists($link_top_level);

    // The test preprocess hook should not have been called.
    self::assertFalse($this->state->get(self::THEME_SUGGESTION_TEST_STATE_KEY, FALSE));

    // Set up a custom hook name to match the preprocess hook declared in the
    // "group_content_menu_theme_hook_suggestion_test" module.
    $this->drupalGet('admin/structure/block/manage/' . $group_menu_block_id);
    $this->submitForm([
      'settings[advanced][theme_hook_suggestion]' => 'custom_hook_name',
    ], 'Save block');

    $this->drupalGet('/group/1');
    $assert->linkExists($link_top_level);

    // The test preprocess hook *should* have been called.
    self::assertTrue($this->state->get(self::THEME_SUGGESTION_TEST_STATE_KEY, FALSE));
  }

  /**
   * Test Expand All Menu Items option.
   */
  public function testExpandAllItems(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    $group_menu_block_id = $this->createAndPlaceGroupMenu();
    $this->enableGroupMenuPlugin([
      'auto_create_group_menu' => TRUE,
      'auto_create_home_link' => TRUE,
      'auto_create_home_link_title' => 'Group home page',
    ]);
    $this->createGroup();

    // Add a parent link.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_top_level = $this->randomString(8);
    $page->fillField('title[0][value]', $link_top_level);
    $page->fillField('link[0][uri]', 'http://example.com');
    $page->pressButton('Save');

    // Add a Child link.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_sub_level = $this->randomString(8);
    $page->fillField('title[0][value]', $link_sub_level);
    $page->fillField('link[0][uri]', 'http://example1.com');
    $page->selectFieldOption('menu_parent', '-- ' . $link_top_level);
    $page->pressButton('Save');

    $this->drupalGet('/group/1');
    $assert->linkNotExists($link_sub_level);

    // Set Block to expand all items.
    $this->drupalGet('admin/structure/block/manage/' . $group_menu_block_id);
    $assert->checkboxNotChecked('settings[expand_all_items]');
    $this->submitForm([
      'settings[level]' => 1,
      'settings[depth]' => 0,
      'settings[expand_all_items]' => 1,
    ], 'Save block');

    // Check if we can now see all items.
    $this->drupalGet('/group/1');
    $assert->linkExists($link_top_level);
    $assert->linkExists($link_sub_level);
  }

  /**
   * Test relative and absolute depth options.
   */
  public function testDepth(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    $group_menu_block_id = $this->createAndPlaceGroupMenu();
    $this->enableGroupMenuPlugin(['auto_create_group_menu' => TRUE]);
    $this->createGroup();

    // Add two parent links, first menu branch A.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_top_level_a = "A_" . $this->randomString(8);
    $page->fillField('title[0][value]', $link_top_level_a);
    $page->fillField('link[0][uri]', 'http://example.com/section_a');
    $page->pressButton('Save');
    // Add top level menu branch B link.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_top_level_b = "B_" . $this->randomString(8);
    $page->fillField('title[0][value]', $link_top_level_b);
    $page->fillField('link[0][uri]', 'http://example.com/section_b');
    $page->pressButton('Save');

    // Add Child links, first menu branch A, pointing to Group 1 home.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_second_level_a = "A.1_Group1_" . $this->randomString(8);
    $page->fillField('title[0][value]', $link_second_level_a);
    // Use "/group/1" so that this link will be active when we GET it.
    $page->fillField('link[0][uri]', '/group/1');
    $page->selectFieldOption('menu_parent', '-- ' . $link_top_level_a);
    $page->pressButton('Save');
    // Add menu branch B child link, pointing to example.com.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_second_level_b = "B.1_" . $this->randomString(8);
    $page->fillField('title[0][value]', $link_second_level_b);
    $page->fillField('link[0][uri]', 'http://example.com/section_b/child_1');
    $page->selectFieldOption('menu_parent', '-- ' . $link_top_level_b);
    $page->pressButton('Save');

    // Add a grand-child links, first menu branch A, pointing to Child A.1.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_third_level_a = "A.1.i_" . $this->randomString(8);
    $page->fillField('title[0][value]', $link_third_level_a);
    $page->fillField('link[0][uri]', 'http://example.com/section_a/child_1/grand-child_i');
    $page->selectFieldOption('menu_parent', '---- ' . $link_second_level_a);
    $page->pressButton('Save');
    // Add menu branch B grand-child link.
    $this->drupalGet('/group/1/menu/1/add-link');
    $assert->statusCodeEquals(200);
    $link_third_level_b = "B.1.i_" . $this->randomString(8);
    $page->fillField('title[0][value]', $link_third_level_b);
    $page->fillField('link[0][uri]', 'http://example.com/section_b/child_1/grand-child_i');
    $page->selectFieldOption('menu_parent', '---- ' . $link_second_level_b);
    $page->pressButton('Save');

    // Set Block to be fully expanded.
    $this->drupalGet('admin/structure/block/manage/' . $group_menu_block_id);
    $this->submitForm([
      'settings[level]' => 1,
      'settings[depth]' => 0,
      'settings[expand_all_items]' => 1,
    ], 'Save block');

    // Check if we can see all menu items in both branches.
    $this->drupalGet('/group/1');
    $assert->linkExists($link_top_level_a);
    $assert->linkExists($link_second_level_a);
    $assert->linkExists($link_third_level_a);
    $assert->linkExists($link_top_level_b);
    $assert->linkExists($link_second_level_b);
    $assert->linkExists($link_third_level_b);

    // Set Block to show only 2 levels of depth.
    $this->drupalGet('admin/structure/block/manage/' . $group_menu_block_id);
    $this->submitForm([
      'settings[depth]' => 2,
    ], 'Save block');

    // Check if we can see only the first and second level menu items in both
    // branches.
    $this->drupalGet('/group/1');
    $assert->linkExists($link_top_level_a);
    $assert->linkExists($link_second_level_a);
    $assert->linkNotExists($link_third_level_a);
    $assert->linkExists($link_top_level_b);
    $assert->linkExists($link_second_level_b);
    $assert->linkNotExists($link_third_level_b);

    // Set Block to absolute level 2.
    $this->drupalGet('admin/structure/block/manage/' . $group_menu_block_id);
    $this->submitForm([
      'settings[level]' => 2,
    ], 'Save block');
    $this->drupalGet('/group/1');

    // Check if we can only see second and third level menu items, in Branch A
    // and none in branch B. See issue #3224816, absolute depth problem.
    $assert->linkNotExists($link_top_level_a);
    $assert->linkExists($link_second_level_a);
    $assert->linkExists($link_third_level_a);
    $assert->linkNotExists($link_top_level_b);
    $assert->linkNotExists($link_second_level_b);
    $assert->linkNotExists($link_third_level_b);

    // Set Block to depth of 1 (absolute level still 2).
    $this->drupalGet('admin/structure/block/manage/' . $group_menu_block_id);
    $this->submitForm([
      'settings[depth]' => 1,
    ], 'Save block');
    $this->drupalGet('/group/1');

    // Check if only second level menu item in A branch is visible, testing
    // that level is properly calculated from current page with absolute depth.
    $assert->linkNotExists($link_top_level_a);
    $assert->linkExists($link_second_level_a);
    $assert->linkNotExists($link_third_level_a);
    $assert->linkNotExists($link_top_level_b);
    $assert->linkNotExists($link_second_level_b);
    $assert->linkNotExists($link_third_level_b);

    // Set Block to have a visibility relative to the active item, and return
    // level to 1 with unlimited depth.
    $this->drupalGet('admin/structure/block/manage/' . $group_menu_block_id);
    $this->submitForm([
      'settings[level]' => 1,
      'settings[depth]' => 0,
      'settings[advanced][relative_visibility]' => 1,
    ], 'Save block');

    // Check if we can now see the second and third level menu items of the A
    // branch, but not the top level item since the second level link is the
    // active item, nor any of the B branch links.
    $this->drupalGet('/group/1');
    $assert->linkNotExists($link_top_level_a);
    $assert->linkExists($link_second_level_a);
    $assert->linkExists($link_third_level_a);
    $assert->linkNotExists($link_top_level_b);
    $assert->linkNotExists($link_second_level_b);
    $assert->linkNotExists($link_third_level_b);

    // Set Block to a relative level of 2 and a depth of 1.
    $this->drupalGet('admin/structure/block/manage/' . $group_menu_block_id);
    $this->submitForm([
      'settings[level]' => 2,
      'settings[depth]' => 1,
    ], 'Save block');

    // Check if we can see the menu link to the sub-page of the current page,
    // but not the current page or its parent, nor any of the B branch.
    // See issue #3224816, relative depth calculation problem.
    $this->drupalGet('/group/1');
    $assert->linkNotExists($link_top_level_a);
    $assert->linkNotExists($link_second_level_a);
    $assert->linkExists($link_third_level_a);
    $assert->linkNotExists($link_top_level_b);
    $assert->linkNotExists($link_second_level_b);
    $assert->linkNotExists($link_third_level_b);
  }

  /**
   * Test the group permissions of this module.
   */
  public function testGroupPermissions(): void {
    $this->createAndPlaceGroupMenu();
    $this->enableGroupMenuPlugin([
      'auto_create_group_menu' => TRUE,
      'auto_create_home_link' => TRUE,
    ]);
    $group = $this->createGroup();

    $node_permission_provider = $this->container->get('group_relation_type.manager')->getPermissionProvider('group_node:article');

    $member = $this->drupalCreateUser([
      'access content',
    ]);
    $group->addMember($member);

    $menu_overview_role = $this->createGroupRole([
      'group_type' => $this->groupType->id(),
      'scope' => PermissionScopeInterface::INDIVIDUAL_ID,
      'permissions' => [
        'access group content menu overview',
        'manage group_content_menu',
        $node_permission_provider->getPermission('create', 'entity', 'any'),
        $node_permission_provider->getPermission('create', 'relationship', 'any'),
      ],
    ]);
    $menu_overview_admin = $this->drupalCreateUser([
      'access content',
    ]);
    $group->addMember($menu_overview_admin, ['group_roles' => $menu_overview_role->id()]);

    $menu_admin_role = $this->createGroupRole([
      'group_type' => $this->groupType->id(),
      'scope' => PermissionScopeInterface::INDIVIDUAL_ID,
      'permissions' => [
        'manage group_content_menu menu items',
        $node_permission_provider->getPermission('create', 'entity', 'any'),
        $node_permission_provider->getPermission('create', 'relationship', 'any'),
      ],
    ]);
    $menu_admin = $this->drupalCreateUser([
      'access content',
    ]);
    $group->addMember($menu_admin, ['group_roles' => $menu_admin_role->id()]);

    $member = $this->drupalCreateUser([
      'access content',
    ]);
    $outsider = $this->drupalCreateUser([
      'access content',
    ]);
    $anonymous = User::load(0);

    // Assign various users membership types.
    $group->addMember($menu_admin, [
      'group_roles' => [$menu_admin_role->id()],
    ]);

    // Group creator is given an admin permission.
    // This permission overrides the check on particular permissions.
    $this->drupalLogin($this->groupCreator);
    $this->assertMenuManagePermissions(200);
    $this->assertMenuItemCrudPermissions(200);
    $this->drupalLogout();

    // Menu overview admin has access to manage, but not items.
    $this->drupalLogin($menu_overview_admin);
    $this->assertMenuManagePermissions(200);
    $this->assertMenuItemCrudPermissions(403);
    $this->drupalLogout();

    // Menu admin has access to items not overview.
    $this->drupalLogin($menu_admin);
    $this->assertMenuManagePermissions(403);
    $this->assertMenuItemCrudPermissions(200);

    // Other users don't have any permissions other than to see the group.
    $this->assertMenuPermissions($member, 403);
    $this->assertMenuPermissions($outsider, 403);
    $this->assertMenuPermissions($anonymous, 403);
  }

  /**
   * Test the translatability of a menu.
   */
  public function testMenuTranslations(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();
    $this->container->get('module_installer')->install([
      'content_translation',
      'language',
    ]);
    $this->rebuildContainer();
    $this->container->get('content_translation.manager')->setEnabled('menu_link_content', 'menu_link_content', TRUE);
    self::enableBundleTranslation('menu_link_content', 'menu_link_content');
    $this->createAndPlaceGroupMenu();
    $this->enableGroupMenuPlugin([
      'auto_create_group_menu' => TRUE,
      'auto_create_home_link' => TRUE,
    ]);
    $group = $this->createGroup();
    $groupContentMenu = $this->container->get('entity_type.manager')
      ->getStorage('group_content_menu')
      ->create([
        'label' => $this->randomString(),
        'bundle' => $this->menuId,
      ]);
    $groupContentMenu->save();
    $group->addRelationship($groupContentMenu, sprintf('group_content_menu:%s', $this->menuId));
    $url = $groupContentMenu->toUrl('translate-menu-link')
      ->setRouteParameter('menu_link_content', 1);
    $this->drupalGet($url);
    $assert->statusCodeEquals(200);
    $assert->pageTextContains('Language Translation Status Operations');

    // Add a languages.
    ConfigurableLanguage::createFromLangcode('es')->save();
    // Rebuild the container so that the new languages are picked up by services
    // that hold a list of languages.
    $this->rebuildContainer();
    $this->drupalGet($url);
    $assert->statusCodeEquals(200);
    $assert->pageTextContains('English (Original language)');
    $page->clickLink('Add');
    $assert->statusCodeEquals(200);
    $page->fillField('title[0][value]', 'Spanish Home - Translation');
    $page->pressButton('Save');
    $assert->pageTextContains('The menu link has been saved.');
    $assert->linkExists('Home - Translation');
  }

  /**
   * Assert menu permissions.
   */
  private function assertMenuPermissions(UserInterface $user, int $status_code): void {
    $assert = $this->assertSession();
    if ($user->isAuthenticated()) {
      $this->drupalLogin($user);
    }
    $this->drupalGet(Url::fromRoute('entity.group.canonical', [
      'group' => 1,
    ]));
    $assert->statusCodeEquals(200);
    $this->assertMenuManagePermissions($status_code);
    $this->assertMenuManagePermissions($status_code);
    if ($user->isAuthenticated()) {
      $this->drupalLogout();
    }
  }

  /**
   * Assert menu manage permissions.
   */
  private function assertMenuManagePermissions(int $status_code): void {
    $assert = $this->assertSession();

    $this->drupalGet(Url::fromRoute('entity.group_content_menu.collection', [
      'group' => 1,
    ]));
    $assert->statusCodeEquals($status_code);
    $this->drupalGet(Url::fromRoute('entity.group_content_menu.add_page', [
      'group' => 1,
    ]));
    $assert->statusCodeEquals($status_code);
    $this->drupalGet(Url::fromRoute('entity.group_content_menu.delete_form', [
      'group' => 1,
      'group_content_menu' => 1,
    ]));
    $assert->statusCodeEquals($status_code);
  }

  /**
   * Assert menu item CRUD permissions.
   */
  private function assertMenuItemCrudPermissions(int $status_code): void {
    $assert = $this->assertSession();

    $this->drupalGet(Url::fromRoute('entity.group_content_menu.edit_form', [
      'group' => 1,
      'group_content_menu' => 1,
    ]));
    $assert->statusCodeEquals($status_code);
    $this->drupalGet(Url::fromRoute('entity.group_content_menu.add_menu_link', [
      'group' => 1,
      'group_content_menu' => 1,
    ]));
    $assert->statusCodeEquals($status_code);
    $this->drupalGet(Url::fromRoute('entity.group_content_menu.edit_menu_link', [
      'group' => 1,
      'group_content_menu' => 1,
      'menu_link_content' => 1,
    ]));
    $assert->statusCodeEquals($status_code);
    $this->drupalGet(Url::fromRoute('entity.group_content_menu.delete_menu_link', [
      'group' => 1,
      'group_content_menu' => 1,
      'menu_link_content' => 1,
    ]));
    $assert->statusCodeEquals($status_code);

    $this->drupalGet('/group/1/content/create/group_node:article');
    if ($status_code === 200) {
      $assert->pageTextContains('Menu settings');
      $assert->pageTextContains('Parent link');
      $assert->fieldExists('menu[enabled]');
    }
    else {
      $assert->pageTextNotContains('Menu settings');
      $assert->fieldNotExists('menu[enabled]');
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function getGlobalPermissions(): array {
    return [
      'administer blocks',
      'administer group content menu types',
      'administer group',
      'administer menu',
    ] + parent::getGlobalPermissions();
  }

  /**
   * @return string
   *   The group menu ID in case it needs to be referenced later.
   */
  private function createAndPlaceGroupMenu(): string {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    // Generate a group content menu type.
    $this->drupalGet('admin/structure/group_content_menu_types');
    $page->clickLink('Add group menu type');
    $assert->statusCodeEquals(200);
    $menu_label = $this->randomString();
    $page->fillField('label', $menu_label);
    $page->fillField('id', $this->menuId);
    $page->pressButton('Save');
    $assert->statusCodeEquals(200);
    $assert->pageTextContains(sprintf('The group menu type %s has been added.', $menu_label));

    // Place the group content menu block.
    $default_theme = $this->config('system.theme')->get('default');
    $group_menu_block = $this->drupalPlaceBlock(sprintf('group_content_menu:%s', $this->menuId), [
      'id' => $default_theme . '_groupmenu',
      'context_mapping' => [
        'group' => '@group.group_route_context:group',
      ],
    ]);
    return $group_menu_block->id();
  }

  private function enableGroupMenuPlugin(array $configuration = []): void {
    $this->container->get('group_relation_type.manager')->clearCachedDefinitions();
    $relationshipTypeStorage = $this->container->get('entity_type.manager')
      ->getStorage('group_relationship_type');
    $relationship_type = $relationshipTypeStorage->createFromPlugin(
      $this->groupType,
      sprintf('group_content_menu:%s', $this->menuId),
      $configuration,
    );
    $relationshipTypeStorage->save($relationship_type);
  }

  /**
   * {@inheritdoc}
   */
  protected function createGroup(array $values = []): GroupInterface {
    $group = parent::createGroup($values + [
      'type' => $this->groupType->id(),
      'uid' => $this->groupCreator->id(),
    ]);
    $admin_membership = $group->getMember($this->groupCreator)->getGroupRelationship();
    $admin_membership->set('group_roles', [$this->adminRole->id()]);
    $admin_membership->save();
    return $group;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc