og-8.x-1.x-dev/tests/src/Unit/Cache/Context/OgPermissionsCacheContextTest.php

tests/src/Unit/Cache/Context/OgPermissionsCacheContextTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\og\Unit\Cache\Context;

use Drupal\Core\Cache\Context\CacheContextInterface;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\PrivateKey;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\Settings;
use Drupal\og\Cache\Context\OgPermissionsCacheContext;
use Drupal\og\MembershipManagerInterface;
use Drupal\og\OgMembershipInterface;
use Drupal\og\OgRoleInterface;
use Drupal\user\EntityOwnerInterface;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;

/**
 * Tests the OG permissions cache context.
 *
 * @group og
 * @coversDefaultClass \Drupal\og\Cache\Context\OgPermissionsCacheContext
 */
class OgPermissionsCacheContextTest extends OgContextCacheContextTestBase {

  use ProphecyTrait;

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

  /**
   * The current user.
   */
  protected AccountInterface|ObjectProphecy $user;

  /**
   * The private key service.
   */
  protected PrivateKey|ObjectProphecy $privateKey;

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

  /**
   * The OG role storage.
   */
  protected EntityStorageInterface|ObjectProphecy $roleStorage;

  /**
   * The config factory.
   */
  protected ConfigFactoryInterface|ObjectProphecy $configFactory;

  /**
   * The OG configuration.
   */
  protected Config|ObjectProphecy $config;

  /**
   * The mocked private key value.
   */
  protected const PRIVATE_KEY = 'private_key';

  /**
   * The mocked hash salt.
   */
  protected const HASH_SALT = 'hash_salt';

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

    $this->group = $this->prophesize(ContentEntityInterface::class);
    $this->group->willImplement(EntityOwnerInterface::class);

    $this->membershipManager = $this->prophesize(MembershipManagerInterface::class);
    $this->user = $this->prophesize(AccountInterface::class);
    $this->privateKey = $this->prophesize(PrivateKey::class);
    $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
    $this->roleStorage = $this->prophesize(EntityStorageInterface::class);
    $this->configFactory = $this->prophesize(ConfigFactoryInterface::class);
    $this->config = $this->prophesize(Config::class);

    $this->entityTypeManager->getStorage('og_role')->willReturn($this->roleStorage);
    $this->configFactory->get('og.settings')->willReturn($this->config->reveal());
    $this->privateKey->get()->willReturn(self::PRIVATE_KEY);

    new Settings(['hash_salt' => self::HASH_SALT]);
  }

  /**
   * {@inheritdoc}
   *
   * @covers ::getContext
   */
  public function testWithoutContext(): void {
    $this->expectGroupContext();

    $this->assertEquals(OgPermissionsCacheContext::NO_CONTEXT, $this->getContextResult());
  }

  /**
   * {@inheritdoc}
   */
  protected function setupExpectedContext($context): void {
    $context += [
      'user_id' => 1,
      'is_authenticated' => TRUE,
      'has_global_admin' => FALSE,
      'group_owner_id' => 0,
      'group_manager_full_access' => FALSE,
      'membership_permissions' => NULL,
      'membership_is_admin' => FALSE,
      'non_member_permissions' => [],
      'is_blocked' => FALSE,
    ];

    $this->expectGroupContext($this->group->reveal());
    $this->group->getEntityTypeId()->willReturn('entity_test');
    $this->group->bundle()->willReturn('bundle');
    $this->group->id()->willReturn('1');
    $this->group->getOwnerId()->willReturn($context['group_owner_id']);

    $this->config->get('group_manager_full_access')->willReturn($context['group_manager_full_access']);

    $this->user->id()->willReturn($context['user_id']);
    $this->user->isAuthenticated()->willReturn($context['is_authenticated']);
    $this->user->hasPermission('administer organic groups')->willReturn($context['has_global_admin']);

    $this->setupMembershipExpectation($context);
  }

  /**
   * Sets up membership expectations for a test scenario.
   */
  protected function setupMembershipExpectation(array $context): void {
    if (!$context['is_authenticated']) {
      return;
    }

    $this->membershipManager
      ->isMember($this->group->reveal(), $context['user_id'], [OgMembershipInterface::STATE_BLOCKED])
      ->willReturn($context['is_blocked']);

    // Blocked users have no permissions so membership and roles don't matter.
    if ($context['is_blocked']) {
      return;
    }

    if ($context['membership_permissions'] !== NULL || $context['membership_is_admin']) {
      $role = $this->prophesize(OgRoleInterface::class);
      $role->isAdmin()->willReturn($context['membership_is_admin']);
      $role->getPermissions()->willReturn($context['membership_permissions'] ?? []);

      $membership = $this->prophesize(OgMembershipInterface::class);
      $membership->getRoles()->willReturn([$role->reveal()]);

      $this->membershipManager
        ->getMembership($this->group->reveal(), $context['user_id'])
        ->willReturn($membership->reveal());
      return;
    }

    $this->membershipManager
      ->getMembership($this->group->reveal(), $context['user_id'])
      ->willReturn(NULL);

    if (!$context['is_blocked']) {
      $anonymous_role = $this->prophesize(OgRoleInterface::class);
      $anonymous_role->getPermissions()->willReturn($context['non_member_permissions']);

      $role_id = 'entity_test-bundle-' . OgRoleInterface::ANONYMOUS;
      $this->roleStorage->load($role_id)->willReturn($anonymous_role->reveal());
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function getCacheContext(): CacheContextInterface {
    return new OgPermissionsCacheContext(
      $this->user->reveal(),
      $this->ogContext->reveal(),
      $this->membershipManager->reveal(),
      $this->entityTypeManager->reveal(),
      $this->privateKey->reveal(),
      $this->configFactory->reveal(),
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function contextProvider(): array {
    $admin_hash = self::hashPermissions([OgPermissionsCacheContext::ADMIN_PERMISSION]);

    return [
      'global admin' => [
        [
          'user_id' => 2,
          'has_global_admin' => TRUE,
        ],
        $admin_hash,
      ],
      'group owner full access' => [
        [
          'user_id' => 3,
          'group_owner_id' => 3,
          'group_manager_full_access' => TRUE,
        ],
        $admin_hash,
      ],
      'admin role' => [
        [
          'user_id' => 4,
          'membership_permissions' => ['ignored'],
          'membership_is_admin' => TRUE,
        ],
        $admin_hash,
      ],
      'member permissions' => [
        [
          'user_id' => 5,
          'membership_permissions' => ['approve', 'view'],
        ],
        self::hashPermissions(['approve', 'view']),
      ],
      'authenticated non-member permissions' => [
        [
          'user_id' => 6,
          'non_member_permissions' => ['view group', 'access content'],
        ],
        self::hashPermissions(['access content', 'view group']),
      ],
      'anonymous user' => [
        [
          'user_id' => 0,
          'is_authenticated' => FALSE,
        ],
        OgPermissionsCacheContext::NO_CONTEXT,
      ],
      'no permissions' => [
        [
          'user_id' => 7,
          'membership_permissions' => [],
        ],
        OgPermissionsCacheContext::NO_CONTEXT,
      ],
    ];
  }

  /**
   * Returns the expected hash for the given permissions.
   */
  protected static function hashPermissions(array $permissions): string {
    sort($permissions);
    return hash('sha256', self::PRIVATE_KEY . self::HASH_SALT . serialize($permissions));
  }

}

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

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