og-8.x-1.x-dev/tests/src/Unit/OgAccessTestBase.php

tests/src/Unit/OgAccessTestBase.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\og\Unit;

use Drupal\Core\Cache\Context\CacheContextsManager;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Tests\UnitTestCase;
use Drupal\og\Entity\OgRole;
use Drupal\og\GroupTypeManagerInterface;
use Drupal\og\MembershipManagerInterface;
use Drupal\og\OgAccess;
use Drupal\og\OgAccessInterface;
use Drupal\og\OgMembershipInterface;
use Drupal\og\OgRoleInterface;
use Drupal\og\PermissionManager;
use Drupal\user\EntityOwnerInterface;
use Drupal\user\UserInterface;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Base class for tests of the OgAccess class.
 */
class OgAccessTestBase extends UnitTestCase {

  use ProphecyTrait;

  /**
   * The mocked config handler.
   */
  protected Config|ObjectProphecy $config;

  /**
   * A mocked test user.
   */
  protected UserInterface|ObjectProphecy $user;

  /**
   * The ID of the test group.
   */
  protected string $groupId;

  /**
   * The entity type ID of the test group.
   */
  protected string $entityTypeId;

  /**
   * The bundle ID of the test group.
   */
  protected string $bundle;

  /**
   * The mocked test group.
   */
  protected EntityInterface|ObjectProphecy $group;

  /**
   * The mocked group manager.
   */
  protected GroupTypeManagerInterface|ObjectProphecy $groupTypeManager;

  /**
   * The mocked permission manager.
   */
  protected PermissionManager|ObjectProphecy $permissionManager;

  /**
   * The OgAccess class, this is the system under test.
   */
  protected OgAccessInterface|ObjectProphecy $ogAccess;

  /**
   * The group membership manager service.
   */
  protected MembershipManagerInterface|ObjectProphecy $membershipManager;

  /**
   * The entity type manager service.
   */
  protected EntityTypeManagerInterface|ObjectProphecy $entityTypeManager;

  /**
   * The membership entity.
   */
  protected OgMembershipInterface|ObjectProphecy $membership;

  /**
   * The OG role.
   */
  protected OgRoleInterface|ObjectProphecy $ogRole;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $this->groupId = $this->randomMachineName();
    $this->entityTypeId = $this->randomMachineName();
    $this->bundle = $this->randomMachineName();

    $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
    $this->membership = $this->prophesize(OgMembershipInterface::class);
    $this->ogRole = $this->prophesize(OgRole::class);

    $this->groupTypeManager = $this->prophesize(GroupTypeManagerInterface::class);
    $this->groupTypeManager->isGroup($this->entityTypeId, $this->bundle)->willReturn(TRUE);

    $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
    $cache_contexts_manager->assertValidTokens(Argument::any())->willReturn(TRUE);

    // It is expected that any access check will retrieve the settings, because
    // it contains an option to give full access to to the group manager.
    $this->config = $this->addCache($this->prophesize(Config::class));
    $this->config->get('group_manager_full_access')->willReturn(FALSE);

    // Whether or not the user has access to a certain operation depends in part
    // on the 'group_manager_full_access' setting which is stored in config.
    // Since the access is cached, this means that from the point of view from
    // the caching system this access varies by the 'og.settings' config object
    // that contains this setting. It is hence expected that the cacheability
    // metadata is retrieved from the config object so it can be attached to the
    // access result object.
    $config_factory = $this->prophesize(ConfigFactoryInterface::class);
    $config_factory->get('og.settings')->willReturn($this->config);

    $this->config->getCacheContexts()->willReturn([]);
    $this->config->getCacheTags()->willReturn([]);
    $this->config->getCacheMaxAge()->willReturn(0);

    // Create a mocked test user.
    $user_id = 2;
    $this->user = $this->prophesize(AccountInterface::class);
    $this->user->isAuthenticated()->willReturn(TRUE);
    $this->user->id()->willReturn($user_id);
    $this->user->hasPermission('administer organic groups')->willReturn(FALSE);

    $this->group = $this->groupEntity()->reveal();

    $this->membershipManager = $this->prophesize(MembershipManagerInterface::class);
    $this->membershipManager->getMembership($this->group, $user_id)->willReturn($this->membership->reveal());
    $this->membershipManager->getMembership($this->group, $user_id, [OgMembershipInterface::STATE_ACTIVE])->willReturn($this->membership->reveal());
    $this->membershipManager->getGroupCount(Argument::any())->willReturn(1);
    $this->membership->getRoles()->willReturn([$this->ogRole->reveal()]);

    // @todo Move to test.
    $this->ogRole->isAdmin()->willReturn(FALSE);
    $this->ogRole->getPermissions()->willReturn(['update group']);

    // Mock all dependencies for the system under test.
    $account_proxy = $this->prophesize(AccountProxyInterface::class);
    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
    $this->permissionManager = $this->prophesize(PermissionManager::class);
    $dispatcher = $this->prophesize(EventDispatcherInterface::class);

    // Instantiate the system under test.
    $this->ogAccess = new OgAccess(
      $config_factory->reveal(),
      $account_proxy->reveal(),
      $module_handler->reveal(),
      $this->groupTypeManager->reveal(),
      $this->permissionManager->reveal(),
      $this->membershipManager->reveal(),
      $dispatcher->reveal()
    );

    $container = new ContainerBuilder();
    $container->set('cache_contexts_manager', $cache_contexts_manager->reveal());
    $container->set('config.factory', $config_factory->reveal());
    $container->set('entity_type.manager', $this->entityTypeManager->reveal());
    $container->set('module_handler', $this->prophesize(ModuleHandlerInterface::class)->reveal());
    $container->set('og.group_type_manager', $this->groupTypeManager->reveal());
    $container->set('og.membership_manager', $this->membershipManager->reveal());

    // This is for caching purposes only.
    $container->set('current_user', $this->user->reveal());
    \Drupal::setContainer($container);
  }

  /**
   * Returns a mocked test group.
   *
   * @param bool $is_owner
   *   Whether or not this test group should be owned by the test user which is
   *   used in the test.
   *
   * @return \Drupal\Core\Entity\EntityInterface|\Prophecy\Prophecy\ObjectProphecy
   *   The test group.
   */
  protected function groupEntity(bool $is_owner = FALSE): EntityInterface|ObjectProphecy {
    $entity_type = $this->prophesize(EntityTypeInterface::class);
    $entity_type->id()->willReturn($this->entityTypeId);

    $group_entity = $this->prophesize(EntityInterface::class);
    if ($is_owner) {
      $group_entity->willImplement(EntityOwnerInterface::class);
      // Our test user is hardcoded to have UID 2.
      $group_entity->getOwnerId()->willReturn(2);
    }
    $group_entity->getEntityType()->willReturn($entity_type);
    $group_entity->getEntityTypeId()->willReturn($this->entityTypeId);
    $group_entity->bundle()->willReturn($this->bundle);
    $group_entity->id()->willReturn($this->groupId);

    return $this->addCache($group_entity);
  }

  /**
   * Mocks the cache methods.
   */
  protected function addCache(ObjectProphecy $prophecy): ObjectProphecy {
    $prophecy->getCacheContexts()->willReturn([]);
    $prophecy->getCacheTags()->willReturn([]);
    $prophecy->getCacheMaxAge()->willReturn(0);
    return $prophecy;
  }

  /**
   * Provides group level permissions to use in access tests.
   *
   * @return array
   *   An array of test permissions.
   */
  public static function permissionsProvider(): array {
    return [
      // In the unit tests we don't really care about the permission name - it
      // can be an arbitrary string; except for
      // OgAccessTest::testUserAccessAdminPermission test which checks for
      // "administer group" permission.
      [OgAccess::UPDATE_GROUP_PERMISSION],
      [OgAccess::ADMINISTER_GROUP_PERMISSION],
    ];
  }

}

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

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