scheduler-8.x-1.x-dev/tests/src/Functional/SchedulerDefaultTimeTest.php
tests/src/Functional/SchedulerDefaultTimeTest.php
<?php
namespace Drupal\Tests\scheduler\Functional;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
/**
* Tests the default time functionality.
*
* The test helper module scheduler_extras is used in testDefaultWithHiddenTime.
* To reduce complexity, and avoid having to create custom entity types, it acts
* on the standard test entity types. Hence the module is only enabled in that
* test, not via a protected static $modules declaration.
*
* @group scheduler
*/
#[Group('scheduler')]
class SchedulerDefaultTimeTest extends SchedulerBrowserTestBase {
/**
* The default time.
*
* @var string
*/
protected $defaultTime;
/**
* The Publish On datetime derived using the default time.
*
* @var \DateTime
*/
protected $publishTime;
/**
* The Unpublish On datetime derived using the default time.
*
* @var \DateTime
*/
protected $unpublishTime;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
// For this test we use a default time of 6:30:15am.
$this->defaultTime = '06:30:15';
$config = $this->config('scheduler.settings');
$config->set('default_time', $this->defaultTime)->save();
// Create DateTime objects to hold the two scheduling dates. This is better
// than using raw unix timestamps because it caters for daylight-saving
// shifts properly.
// @see https://www.drupal.org/project/scheduler/issues/2957490
$this->publishTime = new \DateTime();
$this->publishTime->add(new \DateInterval('P1D'))->setTime(6, 30, 15);
$this->unpublishTime = new \DateTime();
$this->unpublishTime->add(new \DateInterval('P2D'))->setTime(6, 30, 15);
}
/**
* Test the default time functionality during content creation and edit.
*
* This test covers the default scenario where the dates are optional and not
* required. A javascript test covers the cases where the dates are required.
*
* @dataProvider dataStandardEntityTypes
*/
#[DataProvider('dataStandardEntityTypes')]
public function testDefaultTime($entityTypeId, $bundle) {
$this->drupalLogin($this->schedulerUser);
$config = $this->config('scheduler.settings');
$titleField = $this->titleField($entityTypeId);
// We cannot easily test the full validation message as they contain the
// current time which can be one or two seconds in the past. The best we can
// do is check the fixed part of the message as it is when passed to t() in
// Datetime::validateDatetime. Tests only needs to work in English anyway.
$publish_validation_message = 'The Publish on date is invalid.';
$unpublish_validation_message = 'The Unpublish on date is invalid.';
// First test with the "date only" functionality disabled.
$config->set('allow_date_only', FALSE)->save();
// Test that entering a time is required.
$title = 'No time ' . $this->randomMachineName(8);
$edit = [
"{$titleField}[0][value]" => $title,
'publish_on[0][value][date]' => $this->publishTime->format('Y-m-d'),
'unpublish_on[0][value][date]' => $this->unpublishTime->format('Y-m-d'),
];
// Create an entity and check that the expected error messages are shown.
$add_url = $this->entityAddUrl($entityTypeId, $bundle);
$this->drupalGet($add_url);
$this->submitForm($edit, 'Save');
// By default it is required to enter a time when scheduling content for
// publishing and for unpublishing.
$this->assertSession()->pageTextNotMatches('/' . $title . ' is scheduled to be published .* and unpublished .*/');
$this->assertSession()->pageTextContains($publish_validation_message);
$this->assertSession()->pageTextContains($unpublish_validation_message);
// Allow the user to enter only a date with no time.
$config->set('allow_date_only', TRUE)->save();
// Create an entity and check that the validation messages are not shown.
$this->drupalGet($add_url);
$this->submitForm($edit, 'Save');
$this->assertSession()->pageTextNotContains($publish_validation_message);
$this->assertSession()->pageTextNotContains($unpublish_validation_message);
// Get the pattern of the 'long' default date format.
$date_format_storage = $this->container->get('entity_type.manager')->getStorage('date_format');
$long_pattern = $date_format_storage->load('long')->getPattern();
// Check that the scheduled information is shown after saving and that the
// time is correct.
$this->assertSession()->pageTextContains(sprintf('%s is scheduled to be published %s and unpublished %s',
$title, $this->publishTime->format($long_pattern), $this->unpublishTime->format($long_pattern)));
if ($entity = $this->getEntityByTitle($entityTypeId, $title)) {
// Check that the correct scheduled dates are stored in the entity.
$this->assertEquals($this->publishTime->getTimestamp(), (int) $entity->publish_on->value, 'The publish_on value is stored correctly.');
$this->assertEquals($this->unpublishTime->getTimestamp(), (int) $entity->unpublish_on->value, 'The unpublish_on value is stored correctly.');
// Check that the default time has been added to the form on edit.
$this->drupalGet($entity->toUrl('edit-form'));
$this->assertSession()->FieldValueEquals('publish_on[0][value][time]', $this->defaultTime);
$this->assertSession()->FieldValueEquals('unpublish_on[0][value][time]', $this->defaultTime);
}
else {
$this->fail('The expected entity was not found.');
}
}
/**
* Test that the default times are set if the form time elements are hidden.
*
* This test uses the 'scheduler_extras' helper module, which hides the time
* elements of both of the scheduler date input fields.
*
* @dataProvider dataStandardEntityTypes
*/
#[DataProvider('dataStandardEntityTypes')]
public function testDefaultWithHiddenTime($entityTypeId, $bundle) {
\Drupal::service('module_installer')->install(['scheduler_extras']);
$titleField = $this->titleField($entityTypeId);
$this->drupalLogin($this->schedulerUser);
// Allow the user to enter only a date with no time.
$this->config('scheduler.settings')->set('allow_date_only', TRUE)->save();
// Define date values but no time values.
$title = 'Hidden Time Elements ' . $this->randomMachineName(8);
$edit = [
"{$titleField}[0][value]" => $title,
'publish_on[0][value][date]' => $this->publishTime->format('Y-m-d'),
'unpublish_on[0][value][date]' => $this->unpublishTime->format('Y-m-d'),
];
// Create an entity and check that the time fields are hidden.
$this->drupalGet($this->entityAddUrl($entityTypeId, $bundle));
$this->assertSession()->FieldExists('publish_on[0][value][date]');
$this->assertSession()->FieldExists('unpublish_on[0][value][date]');
$this->assertSession()->FieldNotExists('publish_on[0][value][time]');
$this->assertSession()->FieldNotExists('unpublish_on[0][value][time]');
$this->submitForm($edit, 'Save');
// Get the pattern of the 'long' default date format.
$date_format_storage = $this->container->get('entity_type.manager')->getStorage('date_format');
$long_pattern = $date_format_storage->load('long')->getPattern();
// Check that the message has the correct default time after saving.
$this->assertSession()->pageTextContains(sprintf('%s is scheduled to be published %s and unpublished %s',
$title, $this->publishTime->format($long_pattern), $this->unpublishTime->format($long_pattern)));
if ($entity = $this->getEntityByTitle($entityTypeId, $title)) {
// Check that the correct scheduled dates are stored in the node.
$this->assertEquals($this->publishTime->getTimestamp(), (int) $entity->publish_on->value, 'The publish_on value is stored correctly.');
$this->assertEquals($this->unpublishTime->getTimestamp(), (int) $entity->unpublish_on->value, 'The unpublish_on value is stored correctly.');
}
else {
$this->fail('The expected entity was not found.');
}
}
}
