You are here

SchedulerRevisioningTest.php in Scheduler 2.x

Same filename and directory in other branches
  1. 8 tests/src/Functional/SchedulerRevisioningTest.php

File

tests/src/Functional/SchedulerRevisioningTest.php
View source
<?php

namespace Drupal\Tests\scheduler\Functional;

use Drupal\Core\Entity\EntityInterface;

/**
 * Tests revision options when Scheduler publishes or unpublishes content.
 *
 * @group scheduler
 */
class SchedulerRevisioningTest extends SchedulerBrowserTestBase {

  /**
   * Simulates the scheduled (un)publication of an entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to schedule.
   * @param string $action
   *   The action to perform: either 'publish' or 'unpublish'.
   *
   * @return \Drupal\Core\Entity\EntityInterface
   *   The updated entity, after scheduled (un)publication via a cron run.
   */
  protected function scheduleAndRunCron(EntityInterface $entity, string $action) {

    // Simulate scheduling by setting the (un)publication date in the past and
    // running cron.
    $entity->{$action . '_on'} = strtotime('-5 hour', $this->requestTime);
    $entity
      ->save();
    scheduler_cron();
    $storage = $this
      ->entityStorageObject($entity
      ->getEntityTypeId());
    $storage
      ->resetCache([
      $entity
        ->id(),
    ]);
    return $storage
      ->load($entity
      ->id());
  }

  /**
   * Check if the number of revisions for an entity matches a given value.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to check.
   * @param int $expected
   *   The expected number of revisions.
   * @param string $message
   *   The message to display along with the assertion.
   */
  protected function assertRevisionCount(EntityInterface $entity, int $expected, string $message = '') {
    if (!$entity
      ->getEntityType()
      ->isRevisionable()) {
      return;
    }

    // Because we are not deleting any revisions we can take a short cut and use
    // getLatestRevisionId() which will effectively be the number of revisions.
    $storage = $this
      ->entityStorageObject($entity
      ->getEntityTypeId());
    $count = $storage
      ->getLatestRevisionId($entity
      ->id());
    $this
      ->assertEquals($expected, (int) $count, $message);
  }

  /**
   * Tests the creation of new revisions on scheduling.
   *
   * This test is still useful for Commerce Products which are not revisionable
   * because it shows that this entity type can be processed correctly even if
   * the scheduler revision option is incorrectly set on.
   *
   * @dataProvider dataStandardEntityTypes()
   */
  public function testNewRevision($entityTypeId, $bundle) {
    $entityType = $this
      ->entityTypeObject($entityTypeId, $bundle);

    // Create a scheduled entity that is not automatically revisioned.
    $entity = $this
      ->createEntity($entityTypeId, $bundle, [
      'revision' => 0,
    ]);
    $this
      ->assertRevisionCount($entity, 1, 'The initial revision count is 1 when the entity is created.');

    // Ensure entities with past dates are scheduled not published immediately.
    $entityType
      ->setThirdPartySetting('scheduler', 'publish_past_date', 'schedule')
      ->save();

    // First test scheduled publication with revisioning disabled by default.
    $entity = $this
      ->scheduleAndRunCron($entity, 'publish');
    $this
      ->assertRevisionCount($entity, 1, 'No new revision is created by default when entity is published. Revision count remains at 1.');

    // Test scheduled unpublication.
    $entity = $this
      ->scheduleAndRunCron($entity, 'unpublish');
    $this
      ->assertRevisionCount($entity, 1, 'No new revision is created by default when entity is unpublished. Revision count remains at 1.');

    // Enable revisioning.
    $entityType
      ->setThirdPartySetting('scheduler', 'publish_revision', TRUE)
      ->setThirdPartySetting('scheduler', 'unpublish_revision', TRUE)
      ->save();

    // Test scheduled publication with revisioning enabled.
    $entity = $this
      ->scheduleAndRunCron($entity, 'publish');
    $this
      ->assertTrue($entity
      ->isPublished(), 'Entity is published after cron.');
    if ($entity
      ->getEntityType()
      ->isRevisionable()) {
      $this
        ->assertRevisionCount($entity, 2, 'A new revision was created when the entity was published with revisioning enabled.');
      $expected_message = sprintf('Published by Scheduler. The scheduled publishing date was %s.', $this->dateFormatter
        ->format(strtotime('-5 hour', $this->requestTime), 'short'));
      $this
        ->assertEquals($entity
        ->getRevisionLogMessage(), $expected_message, 'The correct message was found in the entity revision log after scheduled publishing.');
    }

    // Test scheduled unpublication with revisioning enabled.
    $entity = $this
      ->scheduleAndRunCron($entity, 'unpublish');
    $this
      ->assertFalse($entity
      ->isPublished(), 'Entity is unpublished after cron.');
    if ($entity
      ->getEntityType()
      ->isRevisionable()) {
      $this
        ->assertRevisionCount($entity, 3, 'A new revision was created when the entity was unpublished with revisioning enabled.');
      $expected_message = sprintf('Unpublished by Scheduler. The scheduled unpublishing date was %s.', $this->dateFormatter
        ->format(strtotime('-5 hour', $this->requestTime), 'short'));
      $this
        ->assertEquals($entity
        ->getRevisionLogMessage(), $expected_message, 'The correct message was found in the entity revision log after scheduled unpublishing.');
    }
  }

  /**
   * Tests the 'touch' option to alter the created date during publishing.
   *
   * @dataProvider dataStandardEntityTypes()
   */
  public function testAlterCreationDate($entityTypeId, $bundle) {

    // Ensure entities with past dates are scheduled not published immediately.
    $entityType = $this
      ->entityTypeObject($entityTypeId, $bundle);
    $entityType
      ->setThirdPartySetting('scheduler', 'publish_past_date', 'schedule')
      ->save();

    // Create an entity with a 'created' date two days in the past.
    $created = strtotime('-2 day', $this->requestTime);
    $settings = [
      'created' => $created,
      'status' => FALSE,
    ];
    $entity = $this
      ->createEntity($entityTypeId, $bundle, $settings);

    // Show that the entity is not published.
    $this
      ->assertFalse($entity
      ->isPublished(), 'The entity is not published.');

    // Schedule the entity for publishing and run cron.
    $entity = $this
      ->scheduleAndRunCron($entity, 'publish');

    // Get the created date from the entity and check that it has not changed.
    $created_after_cron = $entity->created->value;
    $this
      ->assertTrue($entity
      ->isPublished(), 'The entity has been published.');
    $this
      ->assertEquals($created, $created_after_cron, 'The entity creation date is not changed by default.');

    // Set option to change the created date to match the publish_on date.
    $entityType
      ->setThirdPartySetting('scheduler', 'publish_touch', TRUE)
      ->save();

    // Schedule the entity again and run cron.
    $entity = $this
      ->scheduleAndRunCron($entity, 'publish');

    // Check that the created date has changed to match the publish_on date.
    $created_after_cron = $entity->created->value;
    $this
      ->assertEquals(strtotime('-5 hour', $this->requestTime), $created_after_cron, "With 'touch' option set, the entity creation date is changed to match the publishing date.");
  }

}

Classes

Namesort descending Description
SchedulerRevisioningTest Tests revision options when Scheduler publishes or unpublishes content.