You are here

public function OgRoleCacheContextTest::testMembershipsNoSql in Organic groups 8

Tests that the correct cache context key is returned for group members.

Different users might have the identical roles across a number of different groups. Verify that a unique hash is returned for each combination of roles.

This tests the fallback implementation for NoSQL databases. The main implementation is tested in a kernel test.

@covers ::getContext @dataProvider membershipsProvider

Parameters

array $group_memberships: An array that defines the roles test users have in test groups. See the data provider for a description of the format of the array.

array $expected_identical_role_groups: An array containing arrays of user IDs that are expected to have identical cache context keys, since they have identical memberships in the defined test groups.

See also

\Drupal\Tests\og\Kernel\Cache\Context\OgRoleCacheContextTest::testMemberships()

File

tests/src/Unit/Cache/Context/OgRoleCacheContextTest.php, line 138

Class

OgRoleCacheContextTest
Tests the OG role cache context.

Namespace

Drupal\Tests\og\Unit\Cache\Context

Code

public function testMembershipsNoSql(array $group_memberships, array $expected_identical_role_groups) : void {

  // 'Mock' the unmockable singleton that holds the Drupal settings array by
  // instantiating it and populating it with a random salt.
  new Settings([
    'hash_salt' => $this
      ->randomMachineName(),
  ]);

  // Mock the private key that will be returned by the private key handler.
  $this->privateKey
    ->get()
    ->willReturn($this
    ->randomMachineName());

  // Mock the users that are defined in the test case.
  $user_ids = array_keys($group_memberships);
  $users = array_map(function ($user_id) {

    /** @var \Drupal\Core\Session\AccountInterface|\Prophecy\Prophecy\ObjectProphecy $user */
    $user = $this
      ->prophesize(AccountInterface::class);
    $user
      ->id()
      ->willReturn($user_id);
    return $user
      ->reveal();
  }, array_combine($user_ids, $user_ids));

  // Set up the memberships that are expected to be returned from the
  // membership manager.
  $memberships = [];

  // Use incremental IDs for the OgMembership object. These are not actually
  // used for calculating the cache context, but this simulates that in the
  // database no two memberships will have the same ID.
  $membership_id = 0;
  foreach ($group_memberships as $user_id => $group_entity_type_ids) {
    $memberships[$user_id] = [];
    foreach ($group_entity_type_ids as $group_entity_type_id => $group_ids) {
      foreach ($group_ids as $group_id => $roles) {

        // Construct the role IDs that will be returned by the membership.
        $roles_ids = array_map(function (string $role_name) use ($group_entity_type_id) {
          return "{$group_entity_type_id}-bundle-{$role_name}";
        }, $roles);

        // Mock the expected returns of method calls on the membership.

        /** @var \Drupal\og\OgMembershipInterface|\Prophecy\Prophecy\ObjectProphecy $membership */
        $membership = $this
          ->prophesize(OgMembershipInterface::class);
        $membership
          ->getGroupEntityType()
          ->willReturn($group_entity_type_id);
        $membership
          ->getGroupBundle()
          ->willReturn('bundle');
        $membership
          ->getGroupId()
          ->willReturn($group_id);
        $membership
          ->getRolesIds()
          ->willReturn($roles_ids);
        $memberships[$user_id][++$membership_id] = $membership
          ->reveal();
      }
    }
  }

  // Calculate the cache context keys for every user.
  $cache_context_ids = [];
  foreach ($users as $user_id => $user) {

    // When the memberships for every user in the test case are requested from
    // the membership manager, the respective array of memberships will be
    // returned.
    $this->membershipManager
      ->getMemberships($user_id)
      ->willReturn($memberships[$user_id]);
    $cache_context_ids[$user_id] = $this
      ->getContextResult($user);
  }

  // Loop over the expected results and check that all users that have
  // identical roles have the same cache context key.
  foreach ($expected_identical_role_groups as $expected_identical_role_group) {

    // Check that the cache context keys for all users in the group are
    // identical.
    $cache_context_ids_subset = array_intersect_key($cache_context_ids, array_flip($expected_identical_role_group));
    $this
      ->assertTrue(count(array_unique($cache_context_ids_subset)) === 1);

    // Also check that the cache context keys for the other users are
    // different than the ones from our test group.
    $cache_context_id_from_test_group = reset($cache_context_ids_subset);
    $cache_context_ids_from_other_users = array_diff_key($cache_context_ids, array_flip($expected_identical_role_group));
    $this
      ->assertFalse(in_array($cache_context_id_from_test_group, $cache_context_ids_from_other_users));
  }
}