drupalCreateContentType(); $this->content_type = $type->name; variable_set('node_options_' . $this->content_type, array('revision', 'moderation')); // Create and login user. $this->moderator_user = $this->drupalCreateUser(array( 'access content', 'view revisions', 'view all unpublished content', 'view moderation history', 'view moderation messages', 'bypass workbench moderation', "create {$this->content_type} content", "edit any {$this->content_type} content", )); $this->admin_user = $this->drupalCreateUser(array( 'bypass node access', 'administer nodes', 'view revisions', 'view all unpublished content', 'view moderation history', 'view moderation messages', 'bypass workbench moderation', "create {$this->content_type} content", )); } /** * Override DrupalWebTestCase::drupalGetToken() as it does not return the * correct token for the currently logged-in testing user. */ protected function drupalGetToken($value = '') { $session_id = $this->session_id; if (empty($session_id) && !empty($this->loggedInUser)) { $session_id = db_query("SELECT sid FROM {sessions} WHERE uid = :uid ORDER BY timestamp DESC", array(':uid' => $this->loggedInUser->uid))->fetchField(); } return drupal_hmac_base64($value, $session_id . drupal_get_private_key() . drupal_get_hash_salt()); } } class WorkbenchModerationModerateTabTestCase extends WorkbenchModerationTestCase { public static function getInfo() { return array( 'name' => 'Moderation tab', 'description' => 'Create a moderated node publish it using the "Moderate" tab.', 'group' => 'Workbench Moderation', ); } function setUp($modules = array()) { parent::setUp($modules); $this->drupalLogin($this->moderator_user); } function testModerateTab() { $is_moderated = workbench_moderation_node_type_moderated($this->content_type); $this->assertTrue($is_moderated, t('The content type is moderated.')); // Create a new node and make sure it is unpublished. $body_name = 'body[' . LANGUAGE_NONE . '][0]'; $edit = array( 'title' => $this->randomName(), "{$body_name}[value]" => $this->randomString(128), "{$body_name}[format]" => filter_default_format(), ); $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save')); // Get the new node. $node = $this->drupalGetNodeByTitle($edit['title']); $this->assertFalse($node->status, t('New node is unpublished')); $this->assertTrue(isset($node->workbench_moderation), t('Workbench moderation information is present on the node object')); $this->assertFalse(isset($node->workbench_moderation['published']), t('Workbench moderation has no published revision')); // Make sure the "Moderate" tab is accessible. $this->drupalGet("node/{$node->nid}/moderation"); // Attempt to change the moderation state without a token in the link. $this->drupalGet("node/{$node->nid}/moderation/{$node->vid}/change-state/needs_review"); $this->assertResponse(403); // Run the same state change with a valid token, which should succeed. $this->drupalGet("node/{$node->nid}/moderation/{$node->vid}/change-state/needs_review", array( 'query' => array('token' => $this->drupalGetToken("{$node->nid}:{$node->vid}:needs_review")) )); $this->assertResponse(200); $node = node_load($node->nid, NULL, TRUE); $this->assertEqual($node->workbench_moderation['current']->state, 'needs_review', 'Node state changed to Needs Review via callback.'); // Publish the node via the moderation form. $moderate = array('state' => workbench_moderation_state_published()); $this->drupalPost("node/{$node->nid}/moderation", $moderate, t('Apply')); $node = node_load($node->nid, NULL, TRUE); $this->assertTrue(isset($node->workbench_moderation['published']), t('Workbench moderation has a published revision')); // Create a new draft. $new_title = $this->randomName(10) . '_revision1'; $edit = array('title' => $new_title); $this->drupalPost("node/{$node->nid}/edit", $edit, t('Save')); // Load the published and draft revisions. $published = node_load($node->nid, NULL, TRUE); $draft = clone $published; $draft = workbench_moderation_node_current_load($draft); $this->assertEqual($published->vid, $published->workbench_moderation['published']->vid, t('Published revision is loaded by default')); $this->assertTrue($published->status, t('Published revision has status = 1')); $this->assertNotEqual($published->vid, $draft->vid, t('Draft revision is different from the published revision')); } } class WorkbenchModerationDraftTabTestCase extends WorkbenchModerationTestCase { public static function getInfo() { return array( 'name' => 'Draft tab', 'description' => 'Test access to the "Draft" tab and publishing from the mini moderation form on the draft tab.', 'group' => 'Workbench Moderation', 'dependencies' => array( 'workbench', // Workbench is required for the mini moderation form ), ); } function setUp($modules = array()) { $modules = array_merge($modules, array('workbench')); parent::setUp($modules); $this->drupalLogin($this->moderator_user); } function testDraftTab() { // Create a new node and make sure it is unpublished. $body_name = 'body[' . LANGUAGE_NONE . '][0]'; $edit = array( 'title' => $this->randomName(), "{$body_name}[value]" => $this->randomName(128), "{$body_name}[format]" => filter_default_format(), ); $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save')); // Get the new node. $node = $this->drupalGetNodeByTitle($edit['title']); $this->assertFalse($node->status, t('New content is unpublished')); // Publish the node via the moderation form. $moderate = array('state' => workbench_moderation_state_published()); $this->drupalPost("node/{$node->nid}/moderation", $moderate, t('Apply')); $node = node_load($node->nid, NULL, TRUE); $this->assertTrue($node->status, t('Content is published')); // Create a new draft. $edit = array( 'title' => $this->randomName(10) . '_revision1', "{$body_name}[value]" => $this->randomName(128) . '_revision1', ); $this->drupalPost("node/{$node->nid}/edit", $edit, t('Save')); // Can we get to the 'draft' tab? $this->drupalGet("node/{$node->nid}/draft"); $this->assertResponse(200, t('Draft tab is accessible')); // Ensure the new draft content is visible. $this->assertText($edit['title']); $this->assertText($edit["{$body_name}[value]"]); // Moderate the content to a non-draft, non-published state. $middle_state = current(array_diff(array_keys(workbench_moderation_states()), array(workbench_moderation_state_none(), workbench_moderation_state_published()))); $edit = array('state' => $middle_state); $this->drupalPost(NULL, $edit, t('Apply')); // Are we still on node/NID/draft? $this->assertUrl("node/{$node->nid}/draft"); $this->assertResponse(200); // Publish the content. $edit = array('state' => workbench_moderation_state_published()); $this->drupalPost(NULL, $edit, t('Apply')); // Are we redirected to node/NID? $this->assertUrl("node/{$node->nid}"); $this->assertResponse(200); } } class WorkbenchModerationPublishFromNodeFormTestCase extends WorkbenchModerationTestCase { public static function getInfo() { return array( 'name' => 'Publish from node form', 'description' => 'Publish a moderated node from the node form.', 'group' => 'Workbench Moderation', ); } function setUp($modules = array()) { parent::setUp($modules); $this->drupalLogin($this->admin_user); } function testPublishFromNodeForm() { // Create a new node and publish it immediately. $body_name = 'body[' . LANGUAGE_NONE . '][0]'; $edit = array( 'title' => $this->randomName(), "{$body_name}[value]" => $this->randomString(128), "{$body_name}[format]" => filter_default_format(), 'workbench_moderation_state_new' => workbench_moderation_state_published(), ); $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save')); // Get the new node and make sure it is published. $node = $this->drupalGetNodeByTitle($edit['title']); $this->assertTrue(isset($node->workbench_moderation['published']), t('Workbench moderation has a published revision')); $this->assertEqual($node->vid, $node->workbench_moderation['published']->vid, t('Published revision is loaded by default')); $this->assertTrue($node->status, t('Published revision has status = 1')); // Test anonymous access to the published content. $this->drupalLogout(); $this->drupalGet("node/{$node->nid}"); $this->assertResponse(200, t('Anonymous users can access the published content')); } } class WorkbenchModerationUnpublishTestCase extends WorkbenchModerationTestCase { public static function getInfo() { return array( 'name' => 'Unpublish moderated content', 'description' => 'Create and publish a moderated node, then unpublish using the "Moderate" tab.', 'group' => 'Workbench Moderation', ); } function setUp($modules = array()) { parent::setUp($modules); $this->drupalLogin($this->admin_user); } function testUnpublish() { // Create a new node and publish it immediately. Assumes that // WorkbenchModerationPublishFromNodeFormTestCase passes. $body_name = 'body[' . LANGUAGE_NONE . '][0]'; $edit = array( 'title' => $this->randomName(), "{$body_name}[value]" => $this->randomString(128), "{$body_name}[format]" => filter_default_format(), 'workbench_moderation_state_new' => workbench_moderation_state_published(), ); $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save')); $node = $this->drupalGetNodeByTitle($edit['title']); // Unpublish the node via the unpublish confirmation form. $this->drupalPost("node/{$node->nid}/moderation/{$node->vid}/unpublish", array(), t('Unpublish')); $unpublished_node = node_load($node->nid, FALSE, TRUE); $this->assertFalse($unpublished_node->status, t('The node is not published.')); $this->assertFalse(isset($unpublished_node->workbench_moderation['published']), t('Workbench moderation has no published revision.')); } } /** * Tests behavior when title is changed after initial publication of the node. * this matters when aliases exist using the title as a token. */ class WorkbenchRedirectAfterTitleChangeTestCase extends WorkbenchModerationTestCase { public static function getInfo() { return array( 'name' => 'Alias after title change', 'description' => 'Test whether the redirect keeps up with a changed alias', 'group' => 'Workbench Moderation', 'dependencies' => array( 'workbench', // Workbench is required for the mini moderation form. 'pathauto', // Pathauto is required for automatic aliases, without which this test is unnecessary. ), ); } function setUp($modules = array()) { // Make sure Workbench and Pathauto are both enabled. $modules = array_merge($modules, array('workbench', 'pathauto')); parent::setUp($modules); $this->drupalLogin($this->moderator_user); } /** * Tests whether a node with a changed alias correctly redirects upon re-publishing. **/ function testAliasRedirect() { // Create a new draft node. $edit = array( 'title' => $this->randomName(), ); $this->drupalPost("node/add/{$this->content_type}", $edit, t('Save')); // Moderate node to published. $moderate = array('state' => workbench_moderation_state_published()); $this->drupalPost(NULL, $moderate, t('Apply')); // Edit node and change title. $node = $this->drupalGetNodeByTitle($edit['title']); $edit = array('title' => $this->randomName(10) . '_revision1'); $this->drupalPost("node/{$node->nid}/edit", $edit, t('Save')); // Moderate node to published. $moderate = array('state' => workbench_moderation_state_published()); $this->drupalPost(NULL, $moderate, t('Apply')); // Check response code is 200. $this->assertResponse(200); } }