class ScheduledTransitionTest in Scheduled Transitions 8
Same name and namespace in other branches
- 2.x tests/src/Kernel/ScheduledTransitionTest.php \Drupal\Tests\scheduled_transitions\Kernel\ScheduledTransitionTest
Tests basic functionality of scheduled_transitions fields.
@group scheduled_transitions
Hierarchy
- class \Drupal\KernelTests\KernelTestBase extends \PHPUnit\Framework\TestCase implements ServiceProviderInterface uses AssertContentTrait, AssertLegacyTrait, AssertHelperTrait, ConfigTestTrait, PhpunitCompatibilityTrait, RandomGeneratorTrait, TestRequirementsTrait
- class \Drupal\Tests\scheduled_transitions\Kernel\ScheduledTransitionTest uses ContentModerationTestTrait
Expanded class hierarchy of ScheduledTransitionTest
File
- tests/
src/ Kernel/ ScheduledTransitionTest.php, line 24
Namespace
Drupal\Tests\scheduled_transitions\KernelView source
class ScheduledTransitionTest extends KernelTestBase {
use ContentModerationTestTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'entity_test_revlog',
'entity_test',
'scheduled_transitions_test',
'scheduled_transitions',
'content_moderation',
'workflows',
'dynamic_entity_reference',
'user',
'language',
'system',
];
/**
* The service name of a logger.
*
* @var string
*/
protected $testLoggerServiceName = 'test.logger';
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this
->installEntitySchema('st_entity_test');
$this
->installEntitySchema('st_nont_entity_test');
$this
->installEntitySchema('entity_test_revlog');
$this
->installEntitySchema('content_moderation_state');
$this
->installEntitySchema('user');
$this
->installEntitySchema('scheduled_transition');
$this
->installConfig([
'scheduled_transitions',
]);
}
/**
* Tests a scheduled revision.
*
* Publish a revision in the past (not latest).
*/
public function testScheduledRevision() {
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('entity_test_revlog', 'entity_test_revlog');
$workflow
->save();
$author = User::create([
'uid' => 2,
'name' => $this
->randomMachineName(),
]);
$author
->save();
$entity = EntityTestWithRevisionLog::create([
'type' => 'entity_test_revlog',
]);
$entity->moderation_state = 'draft';
$entity
->save();
$entityId = $entity
->id();
$this
->assertEquals(1, $entity
->getRevisionId());
$entity
->setNewRevision();
$entity->moderation_state = 'draft';
$entity
->save();
$this
->assertEquals(2, $entity
->getRevisionId());
$entity
->setNewRevision();
$entity->moderation_state = 'draft';
$entity
->save();
$this
->assertEquals(3, $entity
->getRevisionId());
$newState = 'published';
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => 2,
'author' => $author,
'workflow' => $workflow
->id(),
'moderation_state' => $newState,
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
]);
$scheduledTransition
->save();
$this
->runTransition($scheduledTransition);
$logs = $this
->getLogs();
$this
->assertCount(2, $logs);
$this
->assertEquals('Copied revision #2 and changed from Draft to Published', $logs[0]['message']);
$this
->assertEquals('Deleted scheduled transition #1', $logs[1]['message']);
$revisionIds = $this
->getRevisionIds($entity);
$this
->assertCount(4, $revisionIds);
// Reload the entity.
$entity = EntityTestWithRevisionLog::load($entityId);
$this
->assertEquals('published', $entity->moderation_state->value, sprintf('Entity is now %s.', $newState));
$this
->assertEquals('Scheduled transition: copied revision #2 and changed from Draft to Published', $entity
->getRevisionLogMessage());
}
/**
* Tests a scheduled revision.
*
* Publish the latest revision.
*/
public function testScheduledRevisionLatestNonDefault() {
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('entity_test_revlog', 'entity_test_revlog');
$workflow
->save();
$author = User::create([
'uid' => 2,
'name' => $this
->randomMachineName(),
]);
$author
->save();
$entity = EntityTestWithRevisionLog::create([
'type' => 'entity_test_revlog',
]);
$entity->moderation_state = 'draft';
$entity
->save();
$entityId = $entity
->id();
$this
->assertEquals(1, $entity
->getRevisionId());
$entity
->setNewRevision();
$entity->moderation_state = 'draft';
$entity
->save();
$this
->assertEquals(2, $entity
->getRevisionId());
$entity
->setNewRevision();
$entity->moderation_state = 'draft';
$entity
->save();
$this
->assertEquals(3, $entity
->getRevisionId());
$newState = 'published';
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => 3,
'author' => $author,
'workflow' => $workflow
->id(),
'moderation_state' => $newState,
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
]);
$scheduledTransition
->save();
$this
->runTransition($scheduledTransition);
$logs = $this
->getLogs();
$this
->assertCount(2, $logs);
$this
->assertEquals('Transitioning latest revision from Draft to Published', $logs[0]['message']);
$this
->assertEquals('Deleted scheduled transition #1', $logs[1]['message']);
$revisionIds = $this
->getRevisionIds($entity);
$this
->assertCount(4, $revisionIds);
// Reload the entity.
$entity = EntityTestWithRevisionLog::load($entityId);
$this
->assertEquals('published', $entity->moderation_state->value, sprintf('Entity is now %s.', $newState));
$this
->assertEquals('Scheduled transition: transitioning latest revision from Draft to Published', $entity
->getRevisionLogMessage());
}
/**
* Tests a scheduled revision.
*/
public function testScheduledRevisionRecreateNonDefaultHead() {
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('entity_test_revlog', 'entity_test_revlog');
$workflow
->save();
$author = User::create([
'uid' => 2,
'name' => $this
->randomMachineName(),
]);
$author
->save();
$entity = EntityTestWithRevisionLog::create([
'type' => 'entity_test_revlog',
]);
$entity->name = 'foobar1';
$entity->moderation_state = 'draft';
$entity
->save();
$entityId = $entity
->id();
$this
->assertEquals(1, $entity
->getRevisionId());
$entity
->setNewRevision();
$entity->name = 'foobar2';
$entity->moderation_state = 'draft';
$entity
->save();
$this
->assertEquals(2, $entity
->getRevisionId());
$revision3State = 'draft';
$entity
->setNewRevision();
$entity->name = 'foobar3';
$entity->moderation_state = $revision3State;
$entity
->save();
$this
->assertEquals(3, $entity
->getRevisionId());
$newState = 'published';
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => 2,
'author' => $author,
'workflow' => $workflow
->id(),
'moderation_state' => $newState,
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
'options' => [
[
ScheduledTransition::OPTION_RECREATE_NON_DEFAULT_HEAD => TRUE,
],
],
]);
$scheduledTransition
->save();
$this
->runTransition($scheduledTransition);
$logs = $this
->getLogs();
$this
->assertCount(3, $logs);
$this
->assertEquals('Copied revision #2 and changed from Draft to Published', $logs[0]['message']);
$this
->assertEquals('Reverted Draft revision #3 back to top', $logs[1]['message']);
$this
->assertEquals('Deleted scheduled transition #1', $logs[2]['message']);
$revisionIds = $this
->getRevisionIds($entity);
$this
->assertCount(5, $revisionIds);
// Reload the entity default revision.
$entityStorage = \Drupal::entityTypeManager()
->getStorage('entity_test_revlog');
$entity = EntityTestWithRevisionLog::load($entityId);
$revision4 = $entityStorage
->loadRevision($revisionIds[3]);
$revision5 = $entityStorage
->loadRevision($revisionIds[4]);
$this
->assertEquals($revision4
->getRevisionId(), $entity
->getRevisionId(), 'Default revision is revision 4');
$this
->assertEquals($newState, $entity->moderation_state->value, sprintf('Entity is now %s.', $newState));
$this
->assertEquals($revision4->name->value, 'foobar2');
$this
->assertEquals('Scheduled transition: copied revision #2 and changed from Draft to Published', $revision4
->getRevisionLogMessage());
$this
->assertEquals($revision5->name->value, 'foobar3');
$this
->assertEquals('Scheduled transition: reverted Draft revision #3 back to top', $revision5
->getRevisionLogMessage());
}
/**
* Tests a scheduled revision.
*
* The latest revision is published, ensure it doesnt get republished when
* recreate_non_default_head is TRUE.
*/
public function testScheduledRevisionRecreateDefaultHead() {
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('entity_test_revlog', 'entity_test_revlog');
$workflow
->save();
$author = User::create([
'uid' => 2,
'name' => $this
->randomMachineName(),
]);
$author
->save();
$entity = EntityTestWithRevisionLog::create([
'type' => 'entity_test_revlog',
]);
$entity->name = 'foobar1';
$entity->moderation_state = 'draft';
$entity
->save();
$entityId = $entity
->id();
$this
->assertEquals(1, $entity
->getRevisionId());
$entity
->setNewRevision();
$entity->name = 'foobar2';
$entity->moderation_state = 'draft';
$entity
->save();
$this
->assertEquals(2, $entity
->getRevisionId());
$revision3State = 'published';
$entity
->setNewRevision();
$entity->name = 'foobar3';
$entity->moderation_state = $revision3State;
$entity
->save();
$this
->assertEquals(3, $entity
->getRevisionId());
$newState = 'published';
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => 2,
'author' => $author,
'workflow' => $workflow
->id(),
'moderation_state' => $newState,
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
'options' => [
[
ScheduledTransition::OPTION_RECREATE_NON_DEFAULT_HEAD => TRUE,
],
],
]);
$scheduledTransition
->save();
$this
->runTransition($scheduledTransition);
$logs = $this
->getLogs();
$this
->assertCount(2, $logs);
$this
->assertEquals('Copied revision #2 and changed from Draft to Published', $logs[0]['message']);
$this
->assertEquals('Deleted scheduled transition #1', $logs[1]['message']);
$revisionIds = $this
->getRevisionIds($entity);
$this
->assertCount(4, $revisionIds);
// Reload the entity default revision.
$entityStorage = \Drupal::entityTypeManager()
->getStorage('entity_test_revlog');
$entity = EntityTestWithRevisionLog::load($entityId);
$revision4 = $entityStorage
->loadRevision($revisionIds[3]);
$this
->assertEquals($revision4
->getRevisionId(), $entity
->getRevisionId(), 'Default revision is revision 4');
$this
->assertEquals($newState, $entity->moderation_state->value, sprintf('Entity is now %s.', $newState));
$this
->assertEquals($revision4->name->value, 'foobar2');
$this
->assertEquals('Scheduled transition: copied revision #2 and changed from Draft to Published', $revision4
->getRevisionLogMessage());
}
/**
* Test scheduled transitions are cleaned up when entities are deleted.
*/
public function testScheduledTransitionEntityCleanUp() {
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('entity_test_revlog', 'entity_test_revlog');
$workflow
->save();
$entity = EntityTestWithRevisionLog::create([
'type' => 'entity_test_revlog',
'name' => 'foo',
'moderation_state' => 'draft',
]);
$entity
->save();
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => $entity
->getRevisionId(),
'author' => 1,
'workflow' => $workflow
->id(),
'moderation_state' => 'published',
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
'options' => [
[
'recreate_non_default_head' => TRUE,
],
],
]);
$scheduledTransition
->save();
$entity
->delete();
$this
->assertNull(ScheduledTransition::load($scheduledTransition
->id()));
}
/**
* Test scheduled transitions are cleaned up when translations are deleted.
*/
public function testScheduledTransitionEntityTranslationCleanUp() {
ConfigurableLanguage::createFromLangcode('de')
->save();
ConfigurableLanguage::createFromLangcode('fr')
->save();
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('st_entity_test', 'st_entity_test');
$workflow
->save();
$entity = TestEntity::create([
'type' => 'st_entity_test',
]);
$de = $entity
->addTranslation('de');
$fr = $entity
->addTranslation('fr');
$de->name = 'deName';
$fr->name = 'frName';
$de->moderation_state = 'draft';
$fr->moderation_state = 'draft';
$entity
->save();
$originalDeRevisionId = $de
->getRevisionId();
$originalFrRevisionId = $fr
->getRevisionId();
$this
->assertEquals(1, $entity
->id());
$this
->assertEquals(1, $entity
->getRevisionId());
$this
->assertEquals(1, $originalDeRevisionId);
$this
->assertEquals(1, $originalFrRevisionId);
$author = User::create([
'uid' => 2,
'name' => $this
->randomMachineName(),
]);
$author
->save();
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => $originalDeRevisionId,
// Transition 'de'.
'entity_revision_langcode' => 'de',
'author' => $author,
'workflow' => $workflow
->id(),
'moderation_state' => 'published',
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
]);
$scheduledTransition
->save();
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => $originalFrRevisionId,
// Transition 'fr'.
'entity_revision_langcode' => 'fr',
'author' => $author,
'workflow' => $workflow
->id(),
'moderation_state' => 'published',
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
]);
$scheduledTransition
->save();
$transitions = ScheduledTransition::loadMultiple();
$this
->assertCount(2, $transitions);
// Delete a translation of the entity.
$entity
->removeTranslation('fr');
$entity
->save();
$transitions = ScheduledTransition::loadMultiple();
$this
->assertCount(1, $transitions);
/** @var \Drupal\scheduled_transitions\Entity\ScheduledTransitionInterface $transition */
$transition = reset($transitions);
$this
->assertEquals('de', $transition
->getEntityRevisionLanguage());
}
/**
* Test scheduled transitions are cleaned up when revisions are deleted.
*/
public function testScheduledTransitionEntityRevisionCleanUp() {
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('entity_test_revlog', 'entity_test_revlog');
$workflow
->save();
$entity = EntityTestWithRevisionLog::create([
'type' => 'entity_test_revlog',
'name' => 'foo',
'moderation_state' => 'draft',
]);
$entity
->save();
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => $entity
->getRevisionId(),
'author' => 1,
'workflow' => $workflow
->id(),
'moderation_state' => 'published',
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
'options' => [
[
'recreate_non_default_head' => TRUE,
],
],
]);
$scheduledTransition
->save();
/** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
$storage = \Drupal::entityTypeManager()
->getStorage('entity_test_revlog');
$new_revision = $storage
->createRevision($entity);
$new_revision
->save();
$storage
->deleteRevision($entity
->getRevisionId());
$this
->assertNull(ScheduledTransition::load($scheduledTransition
->id()));
}
/**
* Test when a default or latest revision use a state that no longer exists.
*
* Log message displays appropriate info.
*/
public function testLogsDeletedState() {
$testState1Name = 'foo_default_test_state1';
$testState2Name = 'foo_non_default_test_state2';
$testState3Name = 'published';
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('entity_test_revlog', 'entity_test_revlog');
$configuration = $workflow
->getTypePlugin()
->getConfiguration();
$configuration['states'][$testState1Name] = [
'label' => 'Foo',
'published' => TRUE,
'default_revision' => TRUE,
'weight' => 0,
];
$configuration['states'][$testState2Name] = [
'label' => 'Foo2',
'published' => TRUE,
'default_revision' => FALSE,
'weight' => 0,
];
$workflow
->getTypePlugin()
->setConfiguration($configuration);
$workflow
->save();
$author = User::create([
'uid' => 2,
'name' => $this
->randomMachineName(),
]);
$author
->save();
$entity = EntityTestWithRevisionLog::create([
'type' => 'entity_test_revlog',
]);
$entity->name = 'foobar1';
$entity->moderation_state = $testState1Name;
$entity
->save();
$entityId = $entity
->id();
$this
->assertEquals(1, $entity
->getRevisionId());
$entity
->setNewRevision();
$entity->name = 'foobar3';
$entity->moderation_state = $testState2Name;
$entity
->save();
$this
->assertEquals(2, $entity
->getRevisionId());
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => 1,
'author' => $author,
'workflow' => $workflow
->id(),
'moderation_state' => $testState3Name,
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
'options' => [
[
ScheduledTransition::OPTION_RECREATE_NON_DEFAULT_HEAD => TRUE,
],
],
]);
$scheduledTransition
->save();
$workflow
->getTypePlugin()
->deleteState($testState1Name);
$workflow
->getTypePlugin()
->deleteState($testState2Name);
$workflow
->save();
$type = $workflow
->getTypePlugin();
// Transitioning the first revision, will also recreate the pending revision
// in this workflow because of the OPTION_RECREATE_NON_DEFAULT_HEAD option
// above.
$this
->runTransition($scheduledTransition);
$logBuffer = $this
->getLogBuffer();
$logs = $this
->getLogs($logBuffer);
$this
->assertCount(2, $logs);
$this
->assertEquals('Copied revision #1 and changed from - Unknown state - to Published', $logs[0]['message']);
$this
->assertEquals('Deleted scheduled transition #1', $logs[1]['message']);
// Also check context of logs, to ensure missing states are present as
// 'Missing' strings.
[
2 => $context,
] = $logBuffer[0];
$this
->assertEquals('- Unknown state -', $context['@original_state']);
$this
->assertEquals('- Unknown state -', $context['@original_latest_state']);
$this
->assertEquals('Published', $context['@new_state']);
}
/**
* Tests the moderation state for a specific translation is changed.
*
* Other translations remain unaffected.
*/
public function testTranslationTransition() : void {
ConfigurableLanguage::createFromLangcode('de')
->save();
ConfigurableLanguage::createFromLangcode('fr')
->save();
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('st_entity_test', 'st_entity_test');
$workflow
->save();
$entity = TestEntity::create([
'type' => 'st_entity_test',
]);
$de = $entity
->addTranslation('de');
$fr = $entity
->addTranslation('fr');
$de->name = 'deName';
$fr->name = 'frName';
$de->moderation_state = 'draft';
$fr->moderation_state = 'draft';
$entity
->save();
$originalRevisionId = $entity
->getRevisionId();
$originalDeRevisionId = $de
->getRevisionId();
$originalFrRevisionId = $fr
->getRevisionId();
$this
->assertEquals(1, $entity
->id());
$this
->assertEquals(1, $entity
->getRevisionId());
$this
->assertEquals(1, $originalDeRevisionId);
$this
->assertEquals(1, $originalFrRevisionId);
$author = User::create([
'uid' => 2,
'name' => $this
->randomMachineName(),
]);
$author
->save();
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => 1,
// Transition 'de'.
'entity_revision_langcode' => 'de',
'author' => $author,
'workflow' => $workflow
->id(),
'moderation_state' => 'published',
'transition_on' => (new \DateTime('2 Feb 2018 11am'))
->getTimestamp(),
]);
$scheduledTransition
->save();
$this
->runTransition($scheduledTransition);
// Reload entity.
$entity = TestEntity::load($entity
->id());
// Revision ID increments for all translations.
$this
->assertEquals($originalRevisionId + 1, $entity
->getRevisionId());
$this
->assertEquals($originalFrRevisionId + 1, $entity
->getTranslation('fr')
->getRevisionId());
$this
->assertEquals($originalDeRevisionId + 1, $entity
->getTranslation('de')
->getRevisionId());
$this
->assertEquals('draft', $entity->moderation_state->value);
$this
->assertEquals('draft', $entity
->getTranslation('fr')->moderation_state->value);
// Only 'de' is published.
$this
->assertEquals('published', $entity
->getTranslation('de')->moderation_state->value);
}
/**
* Tests no pending revisions after transition on revision w/no field changes.
*
* After creating a revision, then publishing the entity, create a non default
* revision, without changing any fields. Then schedule this revision to be
* published. Afterwards, the entity should have no more 'pending' revisions
* according to Content Moderation. This pending flag ensures the
* 'Latest revision' tab no longer shows up in the UI.
*/
public function testTransitionNoFieldChanges() : void {
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('st_entity_test', 'st_entity_test');
$workflow
->save();
/** @var \Drupal\Core\Entity\TranslatableRevisionableStorageInterface $entityStorage */
$entityStorage = \Drupal::entityTypeManager()
->getStorage('st_entity_test');
$entity = TestEntity::create([
'type' => 'st_entity_test',
]);
$entity = $entityStorage
->createRevision($entity, FALSE);
$entity->name = 'rev1';
$entity->moderation_state = 'draft';
$entity
->save();
$entity = $entityStorage
->createRevision($entity, FALSE);
$entity->name = 'rev2';
$entity->moderation_state = 'published';
$entity
->save();
/** @var \Drupal\content_moderation\ModerationInformationInterface $moderationInformation */
$moderationInformation = \Drupal::service('content_moderation.moderation_information');
// Do not change any storage fields this time.
$entity = $entityStorage
->createRevision($entity, FALSE);
$entity->moderation_state = 'draft';
$entity
->save();
// At this point there should be a pending revision.
$this
->assertTrue($moderationInformation
->hasPendingRevision($entity));
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => $entity
->getRevisionId(),
'author' => 1,
'workflow' => $workflow
->id(),
'moderation_state' => 'published',
'transition_on' => (new \DateTime('1 year ago'))
->getTimestamp(),
]);
$scheduledTransition
->save();
$this
->runTransition($scheduledTransition);
$this
->assertFalse($moderationInformation
->hasPendingRevision($entity));
}
/**
* Test the changed timestamp is updated when a transition is executed.
*/
public function testChangedTimeUpdated() {
$workflow = $this
->createEditorialWorkflow();
$workflow
->getTypePlugin()
->addEntityTypeAndBundle('st_entity_test', 'st_entity_test');
$workflow
->save();
/** @var \Drupal\Core\Entity\TranslatableRevisionableStorageInterface $entityStorage */
$entityStorage = \Drupal::entityTypeManager()
->getStorage('st_entity_test');
$entity = TestEntity::create([
'type' => 'st_entity_test',
]);
$entity = $entityStorage
->createRevision($entity, FALSE);
$entity->name = 'rev1';
$entity->changed = (new \DateTime('1 year ago'))
->getTimestamp();
$entity->moderation_state = 'draft';
$entity
->save();
$scheduledTransition = ScheduledTransition::create([
'entity' => $entity,
'entity_revision_id' => $entity
->getRevisionId(),
'author' => 1,
'workflow' => $workflow
->id(),
'moderation_state' => 'published',
'transition_on' => (new \DateTime('1 year ago'))
->getTimestamp(),
]);
$scheduledTransition
->save();
$this
->runTransition($scheduledTransition);
/** @var \Drupal\Component\Datetime\TimeInterface $time */
$time = \Drupal::service('datetime.time');
$this
->assertEquals($time
->getRequestTime(), $entityStorage
->load($entity
->id())->changed->value);
}
/**
* Checks and runs any ready transitions.
*
* @param \Drupal\scheduled_transitions\Entity\ScheduledTransitionInterface $scheduledTransition
* A scheduled transition.
*/
protected function runTransition(ScheduledTransitionInterface $scheduledTransition) : void {
$runner = $this->container
->get('scheduled_transitions.runner');
$runner
->runTransition($scheduledTransition);
}
/**
* Gets logs from buffer and cleans out buffer.
*
* Reconstructs logs into plain strings.
*
* @param array|null $logBuffer
* A log buffer from getLogBuffer, or provide an existing value fetched from
* getLogBuffer. This is a workaround for the logger clearing values on
* call.
*
* @return array
* Logs from buffer, where values are an array with keys: severity, message.
*/
protected function getLogs(?array $logBuffer = NULL) : array {
$logs = array_map(function (array $log) {
[
$severity,
$message,
$context,
] = $log;
return [
'severity' => $severity,
'message' => str_replace(array_keys($context), array_values($context), $message),
];
}, $logBuffer ?? $this
->getLogBuffer());
return array_values($logs);
}
/**
* Gets logs from buffer and cleans out buffer.
*
* @array
* Logs from buffer, where values are an array with keys: severity, message.
*/
protected function getLogBuffer() : array {
return $this->container
->get($this->testLoggerServiceName)
->cleanLogs();
}
/**
* Get revision IDs for an entity.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* An entity.
*
* @return int[]
* Revision IDs.
*/
protected function getRevisionIds(EntityInterface $entity) : array {
$entityTypeId = $entity
->getEntityTypeId();
$entityDefinition = \Drupal::entityTypeManager()
->getDefinition($entityTypeId);
$entityStorage = \Drupal::entityTypeManager()
->getStorage($entityTypeId);
/** @var int[] $ids */
$ids = $entityStorage
->getQuery()
->allRevisions()
->condition($entityDefinition
->getKey('id'), $entity
->id())
->execute();
return array_keys($ids);
}
/**
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
parent::register($container);
$container
->register($this->testLoggerServiceName, BufferingLogger::class)
->addTag('logger');
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AssertContentTrait:: |
protected | property | The current raw content. | |
AssertContentTrait:: |
protected | property | The drupalSettings value from the current raw $content. | |
AssertContentTrait:: |
protected | property | The XML structure parsed from the current raw $content. | 1 |
AssertContentTrait:: |
protected | property | The plain-text content of raw $content (text nodes). | |
AssertContentTrait:: |
protected | function | Passes if the raw text IS found escaped on the loaded page, fail otherwise. | |
AssertContentTrait:: |
protected | function | Asserts that a field exists with the given name or ID. | |
AssertContentTrait:: |
protected | function | Asserts that a field exists with the given ID and value. | |
AssertContentTrait:: |
protected | function | Asserts that a field exists with the given name and value. | |
AssertContentTrait:: |
protected | function | Asserts that a field exists in the current page by the given XPath. | |
AssertContentTrait:: |
protected | function | Asserts that a checkbox field in the current page is checked. | |
AssertContentTrait:: |
protected | function | Asserts that a field exists in the current page with a given Xpath result. | |
AssertContentTrait:: |
protected | function | Passes if a link with the specified label is found. | |
AssertContentTrait:: |
protected | function | Passes if a link containing a given href (part) is found. | |
AssertContentTrait:: |
protected | function | Asserts that each HTML ID is used for just a single element. | |
AssertContentTrait:: |
protected | function | Passes if the raw text IS NOT found escaped on the loaded page, fail otherwise. | |
AssertContentTrait:: |
protected | function | Asserts that a field does not exist with the given name or ID. | |
AssertContentTrait:: |
protected | function | Asserts that a field does not exist with the given ID and value. | |
AssertContentTrait:: |
protected | function | Asserts that a field does not exist with the given name and value. | |
AssertContentTrait:: |
protected | function | Asserts that a field does not exist or its value does not match, by XPath. | |
AssertContentTrait:: |
protected | function | Asserts that a checkbox field in the current page is not checked. | |
AssertContentTrait:: |
protected | function | Passes if a link with the specified label is not found. | |
AssertContentTrait:: |
protected | function | Passes if a link containing a given href (part) is not found. | |
AssertContentTrait:: |
protected | function | Passes if a link containing a given href is not found in the main region. | |
AssertContentTrait:: |
protected | function | Asserts that a select option in the current page does not exist. | |
AssertContentTrait:: |
protected | function | Asserts that a select option in the current page is not checked. | |
AssertContentTrait:: |
protected | function | Triggers a pass if the perl regex pattern is not found in raw content. | |
AssertContentTrait:: |
protected | function | Passes if the raw text is NOT found on the loaded page, fail otherwise. | |
AssertContentTrait:: |
protected | function | Passes if the page (with HTML stripped) does not contains the text. | |
AssertContentTrait:: |
protected | function | Pass if the page title is not the given string. | |
AssertContentTrait:: |
protected | function | Passes if the text is found MORE THAN ONCE on the text version of the page. | |
AssertContentTrait:: |
protected | function | Asserts that a select option in the current page exists. | |
AssertContentTrait:: |
protected | function | Asserts that a select option with the visible text exists. | |
AssertContentTrait:: |
protected | function | Asserts that a select option in the current page is checked. | |
AssertContentTrait:: |
protected | function | Asserts that a select option in the current page is checked. | |
AssertContentTrait:: |
protected | function | Asserts that a select option in the current page exists. | |
AssertContentTrait:: |
protected | function | Triggers a pass if the Perl regex pattern is found in the raw content. | |
AssertContentTrait:: |
protected | function | Passes if the raw text IS found on the loaded page, fail otherwise. | |
AssertContentTrait:: |
protected | function | Passes if the page (with HTML stripped) contains the text. | |
AssertContentTrait:: |
protected | function | Helper for assertText and assertNoText. | |
AssertContentTrait:: |
protected | function | Asserts that a Perl regex pattern is found in the plain-text content. | |
AssertContentTrait:: |
protected | function | Asserts themed output. | |
AssertContentTrait:: |
protected | function | Pass if the page title is the given string. | |
AssertContentTrait:: |
protected | function | Passes if the text is found ONLY ONCE on the text version of the page. | |
AssertContentTrait:: |
protected | function | Helper for assertUniqueText and assertNoUniqueText. | |
AssertContentTrait:: |
protected | function | Builds an XPath query. | |
AssertContentTrait:: |
protected | function | Helper: Constructs an XPath for the given set of attributes and value. | |
AssertContentTrait:: |
protected | function | Searches elements using a CSS selector in the raw content. | |
AssertContentTrait:: |
protected | function | Get all option elements, including nested options, in a select. | |
AssertContentTrait:: |
protected | function | Gets the value of drupalSettings for the currently-loaded page. | |
AssertContentTrait:: |
protected | function | Gets the current raw content. | |
AssertContentTrait:: |
protected | function | Get the selected value from a select field. | |
AssertContentTrait:: |
protected | function | Retrieves the plain-text content from the current raw content. | |
AssertContentTrait:: |
protected | function | Get the current URL from the cURL handler. | 1 |
AssertContentTrait:: |
protected | function | Parse content returned from curlExec using DOM and SimpleXML. | |
AssertContentTrait:: |
protected | function | Removes all white-space between HTML tags from the raw content. | |
AssertContentTrait:: |
protected | function | Sets the value of drupalSettings for the currently-loaded page. | |
AssertContentTrait:: |
protected | function | Sets the raw content (e.g. HTML). | |
AssertContentTrait:: |
protected | function | Performs an xpath search on the contents of the internal browser. | |
AssertHelperTrait:: |
protected static | function | Casts MarkupInterface objects into strings. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertTrue() instead. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertEquals() instead. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertSame() instead. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertEquals() instead. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertNotEquals() instead. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertNotSame() instead. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertTrue() instead. | |
AssertLegacyTrait:: |
protected | function | ||
ConfigTestTrait:: |
protected | function | Returns a ConfigImporter object to import test configuration. | |
ConfigTestTrait:: |
protected | function | Copies configuration objects from source storage to target storage. | |
ContentModerationTestTrait:: |
protected | function | Adds an entity type ID / bundle ID to the given workflow. | 1 |
ContentModerationTestTrait:: |
protected | function | Creates the editorial workflow. | 1 |
KernelTestBase:: |
protected | property | Back up and restore any global variables that may be changed by tests. | |
KernelTestBase:: |
protected | property | Back up and restore static class properties that may be changed by tests. | |
KernelTestBase:: |
protected | property | Contains a few static class properties for performance. | |
KernelTestBase:: |
protected | property | ||
KernelTestBase:: |
protected | property | @todo Move into Config test base class. | 7 |
KernelTestBase:: |
protected static | property | An array of config object names that are excluded from schema checking. | |
KernelTestBase:: |
protected | property | ||
KernelTestBase:: |
protected | property | ||
KernelTestBase:: |
protected | property | Do not forward any global state from the parent process to the processes that run the actual tests. | |
KernelTestBase:: |
protected | property | The app root. | |
KernelTestBase:: |
protected | property | Kernel tests are run in separate processes because they allow autoloading of code from extensions. Running the test in a separate process isolates this behavior from other tests. Subclasses should not override this property. | |
KernelTestBase:: |
protected | property | ||
KernelTestBase:: |
protected | property | Set to TRUE to strict check all configuration saved. | 6 |
KernelTestBase:: |
protected | property | The virtual filesystem root directory. | |
KernelTestBase:: |
protected | function | 1 | |
KernelTestBase:: |
protected | function | Bootstraps a basic test environment. | |
KernelTestBase:: |
private | function | Bootstraps a kernel for a test. | |
KernelTestBase:: |
protected | function | Configuration accessor for tests. Returns non-overridden configuration. | |
KernelTestBase:: |
protected | function | Disables modules for this test. | |
KernelTestBase:: |
protected | function | Enables modules for this test. | |
KernelTestBase:: |
protected | function | Gets the config schema exclusions for this test. | |
KernelTestBase:: |
protected | function | Returns the Database connection info to be used for this test. | 1 |
KernelTestBase:: |
public | function | ||
KernelTestBase:: |
private | function | Returns Extension objects for $modules to enable. | |
KernelTestBase:: |
private static | function | Returns the modules to enable for this test. | |
KernelTestBase:: |
protected | function | Initializes the FileCache component. | |
KernelTestBase:: |
protected | function | Installs default configuration for a given list of modules. | |
KernelTestBase:: |
protected | function | Installs the storage schema for a specific entity type. | |
KernelTestBase:: |
protected | function | Installs database tables from a module schema definition. | |
KernelTestBase:: |
protected | function | Returns whether the current test method is running in a separate process. | |
KernelTestBase:: |
protected | function | ||
KernelTestBase:: |
protected | function | Renders a render array. | 1 |
KernelTestBase:: |
protected | function | Sets the install profile and rebuilds the container to update it. | |
KernelTestBase:: |
protected | function | Sets an in-memory Settings variable. | |
KernelTestBase:: |
public static | function | 1 | |
KernelTestBase:: |
protected | function | Sets up the filesystem, so things like the file directory. | 2 |
KernelTestBase:: |
protected | function | Stops test execution. | |
KernelTestBase:: |
protected | function | 6 | |
KernelTestBase:: |
public | function | @after | |
KernelTestBase:: |
protected | function | Dumps the current state of the virtual filesystem to STDOUT. | |
KernelTestBase:: |
public | function | BC: Automatically resolve former KernelTestBase class properties. | |
KernelTestBase:: |
public | function | Prevents serializing any properties. | |
PhpunitCompatibilityTrait:: |
public | function | Returns a mock object for the specified class using the available method. | |
PhpunitCompatibilityTrait:: |
public | function | Compatibility layer for PHPUnit 6 to support PHPUnit 4 code. | |
RandomGeneratorTrait:: |
protected | property | The random generator. | |
RandomGeneratorTrait:: |
protected | function | Gets the random generator for the utility methods. | |
RandomGeneratorTrait:: |
protected | function | Generates a unique random string containing letters and numbers. | 1 |
RandomGeneratorTrait:: |
public | function | Generates a random PHP object. | |
RandomGeneratorTrait:: |
public | function | Generates a pseudo-random string of ASCII characters of codes 32 to 126. | |
RandomGeneratorTrait:: |
public | function | Callback for random string validation. | |
ScheduledTransitionTest:: |
protected static | property |
Modules to enable. Overrides KernelTestBase:: |
|
ScheduledTransitionTest:: |
protected | property | The service name of a logger. | |
ScheduledTransitionTest:: |
protected | function | Gets logs from buffer and cleans out buffer. | |
ScheduledTransitionTest:: |
protected | function | Gets logs from buffer and cleans out buffer. | |
ScheduledTransitionTest:: |
protected | function | Get revision IDs for an entity. | |
ScheduledTransitionTest:: |
public | function |
Registers test-specific services. Overrides KernelTestBase:: |
|
ScheduledTransitionTest:: |
protected | function | Checks and runs any ready transitions. | |
ScheduledTransitionTest:: |
protected | function |
Overrides KernelTestBase:: |
|
ScheduledTransitionTest:: |
public | function | Test the changed timestamp is updated when a transition is executed. | |
ScheduledTransitionTest:: |
public | function | Test when a default or latest revision use a state that no longer exists. | |
ScheduledTransitionTest:: |
public | function | Tests a scheduled revision. | |
ScheduledTransitionTest:: |
public | function | Tests a scheduled revision. | |
ScheduledTransitionTest:: |
public | function | Tests a scheduled revision. | |
ScheduledTransitionTest:: |
public | function | Tests a scheduled revision. | |
ScheduledTransitionTest:: |
public | function | Test scheduled transitions are cleaned up when entities are deleted. | |
ScheduledTransitionTest:: |
public | function | Test scheduled transitions are cleaned up when revisions are deleted. | |
ScheduledTransitionTest:: |
public | function | Test scheduled transitions are cleaned up when translations are deleted. | |
ScheduledTransitionTest:: |
public | function | Tests no pending revisions after transition on revision w/no field changes. | |
ScheduledTransitionTest:: |
public | function | Tests the moderation state for a specific translation is changed. | |
StorageCopyTrait:: |
protected static | function | Copy the configuration from one storage to another and remove stale items. | |
TestRequirementsTrait:: |
private | function | Checks missing module requirements. | |
TestRequirementsTrait:: |
protected | function | Check module requirements for the Drupal use case. | 1 |
TestRequirementsTrait:: |
protected static | function | Returns the Drupal root directory. |