/** * Simulates the scheduled (un)publication of a node. * * @param \Drupal\node\NodeInterface $node * The node to schedule. * @param string $action * The action to perform: either 'publish' or 'unpublish'. Defaults to * 'publish'. * * @return \Drupal\node\NodeInterface * The updated node, after scheduled (un)publication via a cron run. */ protected function schedule(NodeInterface $node, $action = 'publish') { $node_storage = $this->container->get('entity.manager')->getStorage('node'); // Simulate scheduling by setting the (un)publication date in the past and // running cron. $node->{$action . '_on'} = strtotime('-1 day'); $node->save(); scheduler_cron(); $node_storage->resetCache(array($node->id())); return $node_storage->load($node->id()); }
/** * Test the different options for past publication dates. */ public function testSchedulerPastDates() { /** @var EntityStorageInterface $node_storage */ $node_storage = $this->container->get('entity_type.manager')->getStorage('node'); // Log in. $this->drupalLogin($this->adminUser); // Ensure that neither of the scheduling dates are set to be required. $this->nodetype->setThirdPartySetting('scheduler', 'publish_required', FALSE)->setThirdPartySetting('scheduler', 'unpublish_required', FALSE)->save(); // Create an unpublished page node. $node = $this->drupalCreateNode(['type' => $this->nodetype->get('type'), 'status' => FALSE]); // Test the default behavior: an error message should be shown when the user // enters a publication date that is in the past. $edit = ['title[0][value]' => t('Past') . ' ' . $this->randomString(10), 'publish_on[0][value][date]' => \Drupal::service('date.formatter')->format(strtotime('-1 day'), 'custom', 'Y-m-d'), 'publish_on[0][value][time]' => \Drupal::service('date.formatter')->format(strtotime('-1 day'), 'custom', 'H:i:s')]; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and publish')); $this->assertRaw(t("The 'publish on' date must be in the future"), 'An error message is shown by default when the publication date is in the past.'); // Test the 'error' behavior explicitly. $this->nodetype->setThirdPartySetting('scheduler', 'publish_past_date', 'error')->save(); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and publish')); $this->assertRaw(t("The 'publish on' date must be in the future"), 'An error message is shown when the publication date is in the past and the "error" behavior is chosen.'); // Test the 'publish' behavior: the node should be published immediately. $this->nodetype->setThirdPartySetting('scheduler', 'publish_past_date', 'publish')->save(); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and publish')); $this->assertNoRaw(t("The 'publish on' date must be in the future"), 'No error message is shown when the publication date is in the past and the "publish" behavior is chosen.'); $this->assertRaw(t('@type %title has been updated.', ['@type' => t('Basic page'), '%title' => SafeMarkup::checkPlain($edit['title[0][value]'])]), 'The node is saved successfully when the publication date is in the past and the "publish" behavior is chosen.'); // Reload the changed node and check that it is published. $node_storage->resetCache([$node->id()]); /** @var NodeInterface $node */ $node = $node_storage->load($node->id()); $this->assertTrue($node->isPublished(), 'The node has been published immediately when the publication date is in the past and the "publish" behavior is chosen.'); $this->assertNull($node->publish_on->value, 'The node publish_on date has been removed after publishing when the "publish" behavior is chosen.'); // Test the 'schedule' behavior: the node should be unpublished and become // published on the next cron run. $this->nodetype->setThirdPartySetting('scheduler', 'publish_past_date', 'schedule')->save(); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published')); $publish_time = $edit['publish_on[0][value][date]'] . ' ' . $edit['publish_on[0][value][time]']; ### @TODO should use date format from config $this->assertNoRaw(t("The 'publish on' date must be in the future"), 'No error message is shown when the publication date is in the past and the "schedule" behavior is chosen.'); $this->assertRaw(t('@type %title has been updated.', ['@type' => t('Basic page'), '%title' => SafeMarkup::checkPlain($edit['title[0][value]'])]), 'The node is saved successfully when the publication date is in the past and the "schedule" behavior is chosen.'); $this->assertRaw(t('This post is unpublished and will be published @publish_time.', ['@publish_time' => $publish_time]), 'The node is scheduled to be published when the publication date is in the past and the "schedule" behavior is chosen.'); // Reload the node and check that it is unpublished but scheduled correctly. $node_storage->resetCache([$node->id()]); $node = $node_storage->load($node->id()); $this->assertFalse($node->isPublished(), 'The node has been unpublished when the publication date is in the past and the "schedule" behavior is chosen.'); $this->assertEqual(\Drupal::service('date.formatter')->format($node->publish_on->value, 'custom', 'Y-m-d H:i:s'), $publish_time, 'The node is scheduled for the required date'); // Simulate a cron run and check that the node is published. scheduler_cron(); $node_storage->resetCache([$node->id()]); $node = $node_storage->load($node->id()); $this->assertTrue($node->isPublished(), 'The node with publication date in the past and the "schedule" behavior has now been published by cron.'); // Check that an Unpublish date in the past fails validation. $edit = ['title[0][value]' => t('Unpublish in the past') . ' ' . $this->randomString(10), 'unpublish_on[0][value][date]' => \Drupal::service('date.formatter')->format(REQUEST_TIME - 3600, 'custom', 'Y-m-d'), 'unpublish_on[0][value][time]' => \Drupal::service('date.formatter')->format(REQUEST_TIME - 3600, 'custom', 'H:i:s')]; $this->drupalPostForm('node/add/page', $edit, t('Save and publish')); $this->assertRaw(t("The 'unpublish on' date must be in the future"), 'An error message is shown when the unpublish date is in the past.'); }
/** * Tests hook_scheduler_allow(). * * This hook can allow or deny the (un)publication of individual nodes. This * test uses a content type which has checkboxes 'Approved for publication' * and 'Approved for unpublication'. The node may only be published or * unpublished if the appropriate checkbox is ticked. * * @todo Create and update the nodes through the interface so we can check if * the correct messages are displayed. */ public function testAllowedPublishingAndUnpublishing() { if (empty($this->nodetype)) { $this->fail('*** Custom node type ' . $this->custom_type . ' does not exist. Testing abandoned ***'); return; } // Check that the approved fields are shown on the node/add form. $this->drupalLogin($this->webUser); $this->drupalGet('node/add/' . $this->custom_type); $this->assertFieldById('edit-field-approved-publishing-value', '', 'The "Approved for publishing" field is shown on the node form'); $this->assertFieldById('edit-field-approved-unpublishing-value', '', 'The "Approved for unpublishing" field is shown on the node form'); // Create a node that is scheduled but not approved for publication. Then // simulate a cron run, and check that the node is still not published. $node = $this->createUnapprovedNode('publish_on'); scheduler_cron(); $this->node_storage->resetCache(array($node->id())); $node = $this->node_storage->load($node->id()); $this->assertFalse($node->isPublished(), 'An unapproved node is not published during cron processing.'); // Approve the node for publication, simulate a cron run and check that the // node is now published. $this->approveNode($node->id(), 'field_approved_publishing'); scheduler_cron(); $this->node_storage->resetCache(array($node->id())); $node = $this->node_storage->load($node->id()); $this->assertTrue($node->isPublished(), 'An approved node is published during cron processing.'); // Turn on immediate publication of nodes with publication dates in the past // and repeat the tests. It is not needed to simulate cron runs here. $this->nodetype->setThirdPartySetting('scheduler', 'publish_past_date', 'publish')->save(); $node = $this->createUnapprovedNode('publish_on'); $this->assertFalse($node->isPublished(), 'An unapproved node with a date in the past is not published immediately after saving.'); // Check that the node can be approved and published programatically. $this->approveNode($node->id(), 'field_approved_publishing'); $this->node_storage->resetCache(array($node->id())); $node = $this->node_storage->load($node->id()); $this->assertTrue($node->isPublished(), 'An approved node with a date in the past is published immediately via $node->set()->save().'); // Check that a node can be approved and published via edit form. $node = $this->createUnapprovedNode('publish_on'); $this->drupalPostForm('node/' . $node->id() . '/edit', ['field_approved_publishing[value]' => '1'], t('Save')); $this->node_storage->resetCache(array($node->id())); $node = $this->node_storage->load($node->id()); $this->assertTrue($node->isPublished(), 'An approved node with a date in the past is published immediately after saving via edit form.'); // Test approval for unpublishing. This is simpler than the test sequence // for publishing, because the 'immediate' option is not applicable. // Create a node that is scheduled but not approved for unpublication. Then // simulate a cron run, and check that the node is still published. $node = $this->createUnapprovedNode('unpublish_on'); scheduler_cron(); $this->node_storage->resetCache(array($node->id())); $node = $this->node_storage->load($node->id()); $this->assertTrue($node->isPublished(), 'An unapproved node is not unpublished during cron processing.'); // Approve the node for unpublishing, simulate a cron run and check that // the node is now unpublished. $this->approveNode($node->id(), 'field_approved_unpublishing'); scheduler_cron(); $this->node_storage->resetCache(array($node->id())); $node = $this->node_storage->load($node->id()); $this->assertFalse($node->isPublished(), 'An approved node is unpublished during cron processing.'); }