og-8.x-1.x-dev/tests/src/Functional/GroupSubscribeTest.php

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

declare(strict_types=1);

namespace Drupal\Tests\og\Functional;

use Drupal\user\UserInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\og\Traits\OgMembershipCreationTrait;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\node\NodeInterface;
use Drupal\og\Entity\OgMembershipType;
use Drupal\og\Entity\OgRole;
use Drupal\og\Og;
use Drupal\og\OgMembershipInterface;
use Drupal\og\OgRoleInterface;

/**
 * Tests subscribe and un-subscribe to groups.
 *
 * @group og
 */
class GroupSubscribeTest extends BrowserTestBase {

  use OgMembershipCreationTrait;

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['node', 'og'];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * Test entity group.
   */
  protected NodeInterface $groupB1No1;

  /**
   * Test entity group.
   */
  protected NodeInterface $groupB2No1;

  /**
   * Test entity group.
   */
  protected NodeInterface $groupB1No2Unpublished;

  /**
   * Test entity group.
   */
  protected NodeInterface $nonGroup;

  /**
   * Test entity group.
   */
  protected NodeInterface $groupB3No1;

  /**
   * A group bundle name.
   */
  protected string $groupBundle1;

  /**
   * A group bundle name.
   */
  protected string $groupBundle2;

  /**
   * A group bundle name.
   */
  protected string $groupBundle3;

  /**
   * A membership type bundle name.
   */
  protected string $membershipTypeBundle;

  /**
   * A non-group bundle name.
   */
  protected string $nonGroupBundle;

  /**
   * Test normal user with no connection to the organic group.
   */
  protected UserInterface $normalUser;

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

    // Create bundles.
    $this->groupBundle1 = mb_strtolower($this->randomMachineName());
    NodeType::create(['type' => $this->groupBundle1])->save();
    $this->groupBundle2 = mb_strtolower($this->randomMachineName());
    NodeType::create(['type' => $this->groupBundle2])->save();
    $this->groupBundle3 = mb_strtolower($this->randomMachineName());
    NodeType::create(['type' => $this->groupBundle3])->save();
    $this->nonGroupBundle = mb_strtolower($this->randomMachineName());
    NodeType::create(['type' => $this->nonGroupBundle])->save();
    $this->membershipTypeBundle = mb_strtolower($this->randomMachineName());
    NodeType::create(['type' => $this->membershipTypeBundle])->save();

    // Define the entities as groups.
    Og::groupTypeManager()->addGroup('node', $this->groupBundle1);
    Og::groupTypeManager()->addGroup('node', $this->groupBundle2);
    Og::groupTypeManager()->addGroup('node', $this->groupBundle3);

    // Create node author user.
    $user = $this->createUser();

    // Create test groups. The first group bundle has the
    // 'subscribe without approval' permission.
    $this->groupB1No1 = Node::create([
      'type' => $this->groupBundle1,
      'title' => $this->randomString(),
      'uid' => $user->id(),
    ]);
    $this->groupB1No1->save();

    // An unpublished group.
    $this->groupB1No2Unpublished = Node::create([
      'type' => $this->groupBundle1,
      'title' => $this->randomString(),
      'uid' => $user->id(),
      'status' => NodeInterface::NOT_PUBLISHED,
    ]);
    $this->groupB1No2Unpublished->save();

    // A group which is using default permissions; it grants the 'subscribe'
    // permission to non-members.
    $this->groupB2No1 = Node::create([
      'type' => $this->groupBundle2,
      'title' => $this->randomString(),
      'uid' => $user->id(),
    ]);
    $this->groupB2No1->save();

    // Create non-group.
    $this->nonGroup = Node::create([
      'type' => $this->nonGroupBundle,
      'title' => $this->randomString(),
      'uid' => $user->id(),
    ]);
    $this->nonGroup->save();

    // A group which is closed for subscription. It grants neither 'subscribe'
    // nor 'subscribe without approval'.
    $this->groupB3No1 = Node::create([
      'type' => $this->groupBundle3,
      'title' => $this->randomString(),
      'uid' => $user->id(),
    ]);
    $this->groupB3No1->save();

    // Grant the permission to 'subscribe without approval' to the first group
    // type.
    OgRole::getRole('node', $this->groupBundle1, OgRoleInterface::ANONYMOUS)
      ->grantPermission('subscribe without approval')
      ->save();

    // Revoke the permission to subscribe from the third group type.
    OgRole::getRole('node', $this->groupBundle3, OgRoleInterface::ANONYMOUS)
      ->revokePermission('subscribe')
      ->save();

    // Create a new membership type.
    $membership_type = OgMembershipType::create([
      'type' => $this->membershipTypeBundle,
      'name' => $this->randomString(),
    ]);
    $membership_type->save();

    $this->normalUser = $this->drupalCreateUser();
  }

  /**
   * Tests access to subscribe page.
   */
  public function testSubscribeAccess(): void {

    // We don't use a provider function, as it makes the test run much slower.
    $scenarios = [
      // Group with active membership.
      [
        'entity' => $this->groupB1No1,
        // Don't set the membership type. "Default" will be used.
        'membership_type' => '',
        'code' => 200,
        'skip_approval' => TRUE,
        'private' => FALSE,
      ],
      [
        'entity' => $this->groupB1No1,
        // Explicitly set the membership type.
        'membership_type' => OgMembershipInterface::TYPE_DEFAULT,
        'code' => 200,
        'skip_approval' => TRUE,
        'private' => FALSE,
      ],
      [
        'entity' => $this->groupB1No1,
        // Set invalid membership type.
        'membership_type' => mb_strtolower($this->randomMachineName()),
        'code' => 404,
      ],
      // Group with pending membership.
      [
        'entity' => $this->groupB2No1,
        'code' => 200,
        'skip_approval' => FALSE,
        'private' => FALSE,
      ],

      // Entity is un-accessible to the user, but we still allow to subscribe to
      // it. Since it's "private" the default membership will be pending,
      // even though the permission is "subscribe without approval".
      [
        'entity' => $this->groupB1No2Unpublished,
        'code' => 200,
        'skip_approval' => FALSE,
        'private' => TRUE,
      ],

      // A non-group entity.
      [
        'entity' => $this->nonGroup,
        'code' => 403,
      ],

      // A group which doesn't allow new subscriptions.
      [
        'entity' => $this->groupB3No1,
        'code' => 403,
      ],

      // A non existing entity type.
      [
        'entity_type_id' => mb_strtolower($this->randomMachineName()),
        'entity_id' => 1,
        // @todo This currently returns a 500 error due to a bug in core. Change
        //   this to a 403 or 404 when the bug is fixed.
        // @see https://www.drupal.org/node/2786897
        'code' => version_compare(\Drupal::VERSION, '9.1.4', '>=') ? 404 : 500,
      ],

      // A non existing entity ID.
      [
        'entity_type_id' => 'node',
        'entity_id' => rand(1000, 2000),
        'code' => 404,
      ],
    ];

    foreach ($scenarios as $scenario) {
      // Use a different user for each scenario so they have no existing
      // memberships.
      $new_user = $this->drupalCreateUser();
      $this->drupalLogin($new_user);
      $entity = NULL;
      /** @var \Drupal\Core\Entity\EntityInterface $entity */
      if (!empty($scenario['entity'])) {
        $entity = $scenario['entity'];
        $entity_type_id = $entity->getEntityTypeId();
        $entity_id = $entity->id();
      }
      else {
        $entity_type_id = $scenario['entity_type_id'];
        $entity_id = $scenario['entity_id'];
      }

      $path = "group/$entity_type_id/$entity_id/subscribe";

      if (!empty($scenario['membership_type'])) {
        // Add the membership type.
        $path .= '/' . $scenario['membership_type'];
      }

      $this->drupalGet($path);
      $this->assertSession()->statusCodeEquals($scenario['code']);

      if ($scenario['code'] !== 200) {
        continue;
      }

      if ($scenario['skip_approval']) {
        $this->assertSession()->elementNotExists('css', '#edit-og-membership-request-0-value');
        $text = 'Are you sure you want to join the group';
        $expected_state = [OgMembershipInterface::STATE_ACTIVE];
      }
      else {
        // The text area to explain the request to join.
        $this->assertSession()->elementExists('css', '#edit-og-membership-request-0-value');
        $text = 'Are you sure you want to request a subscription to the group';
        $expected_state = [OgMembershipInterface::STATE_PENDING];
      }
      $this->assertSession()->pageTextContains($text);
      // The user should not be able to change their role or state, due to
      // field permissions in
      // \Drupal\og\OgMembershipAccessControlHandler::checkFieldAccess().
      $this->assertSession()->elementNotExists('css', '#edit-roles');
      $this->assertSession()->elementNotExists('css', '#edit-state');
      $this->click('#edit-submit');
      $this->assertSession()->statusCodeEquals(200);
      /** @var \Drupal\og\MembershipManager $membership_manager */
      $membership_manager = $this->container->get('og.membership_manager');
      $this->assertTrue($membership_manager->isMember($entity, $new_user->id(), $expected_state));

      // Assert title appears only for accessible groups.
      if ($scenario['private']) {
        // Group's title shouldn't appear anywhere.
        $this->assertSession()->responseNotContains($entity->label());
      }
      else {
        $this->assertSession()->pageTextContains($entity->label());
      }
    }
  }

  /**
   * Tests access to un-subscribe page.
   */
  public function testUnSubscribeAccess(): void {
    $this->createOgMembership($this->groupB1No1, $this->normalUser);

    $this->drupalLogin($this->normalUser);

    $scenarios = [
      $this->groupB1No1->id() => 200,
      $this->groupB2No1->id() => 403,
    ];

    foreach ($scenarios as $entity_id => $code) {
      $path = "group/node/$entity_id/unsubscribe";

      $this->drupalGet($path);
      $this->assertSession()->statusCodeEquals($code);
    }
  }

}

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

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