content_lock-8.x-2.1/tests/src/Functional/ContentLockTimeoutTest.php

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

declare(strict_types=1);

namespace Drupal\Tests\content_lock\Functional;

use Drupal\block_content\BlockContentInterface;
use Drupal\content_lock\ContentLock\ContentLockInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\NodeInterface;
use Drupal\taxonomy\TermInterface;
use Drupal\taxonomy\VocabularyInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait;
use Drupal\Tests\Traits\Core\CronRunTrait;
use Drupal\user\UserInterface;

/**
 * Test content_lock timeout functionality.
 *
 * @group content_lock
 */
class ContentLockTimeoutTest extends BrowserTestBase {

  use TaxonomyTestTrait;
  use CronRunTrait;

  /**
   * Modules to install.
   *
   * @var array
   */
  protected static $modules = [
    'system',
    'language',
    'user',
    'node',
    'field',
    'field_ui',
    'taxonomy',
    'block',
    'block_content',
    'content_lock',
    'content_lock_timeout_test',
  ];

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

  /**
   * Array standard permissions for normal user.
   *
   * @var string[]
   */
  protected array $permissions1;

  /**
   * Array standard permissions for user2.
   *
   * @var string[]
   */
  protected array $permissions2;

  /**
   * User with permission to administer entities.
   */
  protected UserInterface $adminUser;

  /**
   * Standard User.
   */
  protected UserInterface $user1;

  /**
   * Standard User.
   */
  protected UserInterface $user2;

  /**
   * A node created.
   */
  protected NodeInterface $article1;

  /**
   * A vocabulary created.
   */
  protected VocabularyInterface $vocabulary;

  /**
   * A term created.
   */
  protected TermInterface $term1;

  /**
   * A Block created.
   */
  protected BlockContentInterface $block1;

  /**
   * Lock service.
   */
  protected ContentLockInterface $lockService;

  /**
   * Setup and Rebuild node access.
   */
  public function setUp(): void {
    parent::setUp();

    $this->drupalCreateContentType(['type' => 'article']);

    $this->adminUser = $this->drupalCreateUser([
      'edit any article content',
      'delete any article content',
      'administer nodes',
      'administer content types',
      'administer users',
      'administer blocks',
      'administer taxonomy',
      'administer content lock',
    ]);

    $this->permissions1 = [
      'create article content',
      'edit any article content',
      'delete any article content',
      'access content',
      'administer blocks',
      'administer taxonomy',
    ];

    $this->permissions2 = [
      'create article content',
      'edit any article content',
      'delete any article content',
      'access content',
      'administer blocks',
      'administer taxonomy',
      'break content lock',
    ];

    // Create articles nodes.
    $this->article1 = $this->drupalCreateNode([
      'type' => 'article',
      'title' => 'Article 1',
    ]);

    // Create vocabulary and terms.
    $this->vocabulary = $this->createVocabulary();
    $this->term1 = $this->createTerm($this->vocabulary);

    $this->user1 = $this->drupalCreateUser($this->permissions1);
    $this->user2 = $this->drupalCreateUser($this->permissions2);

    node_access_rebuild();
    $this->cronRun();

    $this->drupalLogin($this->adminUser);
    $edit = [
      // Set timeout to 10 minutes.
      'timeout' => 10,
    ];
    $this->drupalGet('/admin/config/content/content_lock');
    $this->submitForm($edit, 'Save configuration');
    // Refresh the container so the lock service is updated with the new config.
    $this->rebuildAll();

    $this->lockService = \Drupal::service('content_lock');
  }

  /**
   * Test content lock timeout with nodes.
   */
  public function testContentLockNode(): void {
    // We protect the bundle created.
    $this->drupalLogin($this->adminUser);
    $edit = [
      'node[bundles][article]' => 1,
    ];
    $this->drupalGet('/admin/config/content/content_lock');
    $this->submitForm($edit, 'Save configuration');

    $this->doTestForEntity($this->article1);
  }

  /**
   * Test content lock timeout with terms.
   */
  public function testContentLockTerm(): void {
    // We protect the bundle created.
    $this->drupalLogin($this->adminUser);
    $edit = [
      'taxonomy_term[bundles][' . $this->term1->bundle() . ']' => 1,
    ];
    $this->drupalGet('/admin/config/content/content_lock');
    $this->submitForm($edit, 'Save configuration');

    $this->doTestForEntity($this->term1);
  }

  /**
   * Run the same tests for node, block and term.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to tests.
   *
   * @throws \Drupal\Core\Entity\EntityMalformedException
   */
  protected function doTestForEntity(EntityInterface $entity): void {
    // We lock article1.
    $this->drupalLogin($this->user2);

    $this->lockContentByUser1($entity);

    // Content should be locked.
    $this->drupalGet($entity->toUrl('edit-form'));
    $this->assertSession()->pageTextContains("This content is being edited by the user {$this->user1->getDisplayName()} and is therefore locked to prevent other users changes.");

    // Jump 9 minutes into the future and run cron. The lock should not be
    // released.
    \Drupal::time()->setTimePatch(9 * 60);
    $this->cronRun();
    $this->assertLockOnContent($entity);

    // Jump into future to release lock.
    \Drupal::time()->setTimePatch(11 * 60);
    $this->cronRun();
    \Drupal::time()->setTimePatch(0);

    // Content should be unlocked by cron.
    $this->assertNoLockOnContent($entity);
    $this->drupalGet($entity->toUrl('edit-form'));
    $this->assertSession()->pageTextContains('This content is now locked against simultaneous editing.');
    $this->assertLockOnContent($entity);

    // Content should be unlocked when the last session of a user is closed by
    // logging out.
    $this->drupalLogout();

    // There should be no lock on the content after logout.
    $this->assertNoLockOnContent($entity);

    $this->lockContentByUser1($entity);

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

    // Jump 9 minutes into the future and the content should still be locked.
    \Drupal::time()->setTimePatch(9 * 60);
    $this->drupalGet($entity->toUrl('edit-form'));
    $this->assertSession()->pageTextContains("This content is being edited by the user {$this->user1->getDisplayName()} and is therefore locked to prevent other users changes.");

    // Jump into the future.
    \Drupal::time()->setTimePatch(11 * 60);
    $this->assertStaleLockOnContent($entity);
    // Lock should be released.
    $this->drupalGet($entity->toUrl('edit-form'));
    $this->assertSession()->pageTextContains('This content is now locked by you against simultaneous editing.');
  }

  /**
   * Create lock from user 1.
   *
   * As logout is removing locks, it is only possible to set a lock from another
   * user with the lock service.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity which should be locked.
   */
  protected function lockContentByUser1(EntityInterface $entity): void {
    $this->lockService->releaseAllUserLocks((int) $this->user2->id());
    $this->lockService->locking($entity, 'edit', (int) $this->user1->id());
    $lock = $this->lockService->fetchLock($entity, 'edit');
    $this->assertNotNull($lock, 'Lock present');
    $this->assertEquals($this->user1->label(), $lock->name, 'Lock present for correct user.');
  }

  /**
   * Assert if no lock is present for content.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity which should not have a lock.
   */
  protected function assertNoLockOnContent(EntityInterface $entity): void {
    $lock = $this->lockService->fetchLock($entity, 'edit', TRUE);
    $this->assertFalse($lock, 'No lock present.');
  }

  /**
   * Assert if lock is present for content.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity which should not have a lock.
   */
  protected function assertLockOnContent(EntityInterface $entity): void {
    $lock = $this->lockService->fetchLock($entity, 'edit');
    $this->assertInstanceOf(\StdClass::class, $lock, 'Lock present.');
  }

  /**
   * Assert if stale lock is present for content.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity which should not have a lock.
   */
  protected function assertStaleLockOnContent(EntityInterface $entity): void {
    $lock = $this->lockService->fetchLock($entity, 'edit');
    $this->assertFalse($lock, 'No lock present.');
    $lock = $this->lockService->fetchLock($entity, 'edit', include_stale_locks: TRUE);
    $this->assertInstanceOf(\StdClass::class, $lock, 'Stale lock present.');
  }

}

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

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