You are here

workbench_moderation.test in Workbench Moderation 7.2

Same filename and directory in other branches
  1. 7.3 tests/workbench_moderation.test
  2. 7 tests/workbench_moderation.test

File

tests/workbench_moderation.test
View source
<?php

/**
 * @file
 * workbench_moderation.test
 */

/**
 * Tests for Workbench Moderation.
 */
class WorkbenchModerationWebTestCase extends DrupalWebTestCase {
  function setup() {

    // Ensure we process passed in modules.
    $modules = func_get_args();
    if (isset($modules[0]) && is_array($modules[0])) {
      $modules = $modules[0];
    }
    $modules += array(
      'state_machine',
      'state_flow',
      'state_flow_entity',
      'workbench_moderation',
      'workbench_workflows',
      'views',
    );
    parent::setup($modules);

    // Install the basic workflow.
    module_load_include('inc', 'workbench_workflows', 'includes/workbench_workflows.starter');
    workbench_workflows_import_starter_exportables();

    // Ensure the just imported objects are known and not stuck in the cache.
    ctools_export_load_object_reset();

    // Ensure the new permissions introduced by the import are known.
    $this
      ->checkPermissions(array(), TRUE);
    $permissions = array(
      'administer nodes',
      'bypass node access',
      'use workbench_moderation my drafts tab',
      'use workbench_moderation needs review tab',
      'administer_workbench_workflows',
      'access administration pages',
      'administer site configuration',
      'administer content revisions',
    );
    $this->admin_user = $this
      ->drupalCreateUser($permissions);
    $this
      ->drupalLogin($this->admin_user);
  }

  /**
   * This test verifies that workflows are not used after being disabled.
   *
   * The test also sets the variable to ignore nodes that have no workflow set.
   *
   * The flow of this test is to
   * 1. Go to the node add page to verify that a workflow events are present.
   * 2. Disable the one workflow.
   * 3. Go back to the node add page to verify that no workflow events are present.
   */
  function testOfDisbablingWorkflow() {

    // Set the variable that will cause the ignore class to be picked up if no
    // other workflow is explicitly set.
    variable_set('workbench_workflows_default_to_ignore', TRUE);

    // Assert that workflow events are available.
    $this
      ->drupalGet("node/add/article");
    $this
      ->assertResponse(200);
    $xpath_string = "//select[@id=:select_id]";
    $xpath_replacements = array(
      ':select_id' => 'edit-event',
    );
    $tr = $this
      ->xpath($xpath_string, $xpath_replacements);
    $this
      ->assertEqual(count($tr), 1, 'There is a workflow available on the node add form.');

    // Go to the Workflows admin page and disable the only workflow.
    $this
      ->drupalGet("admin/config/workflow/workbench-workflows/workflows");
    $this
      ->assertResponse(200);

    // Click the disable link.
    $this
      ->clickLink('Disable');

    // Assert that workflow events are not available.
    $this
      ->drupalGet("node/add/article");
    $this
      ->assertResponse(200);
    $xpath_string = "//select[@id=:select_id]";
    $xpath_replacements = array(
      ':select_id' => 'edit-event',
    );
    $tr = $this
      ->xpath($xpath_string, $xpath_replacements);
    $this
      ->assertEqual(count($tr), 0, 'There is not workflow available on the node add form.');
  }

  /**
   * Helper function to check for duplicate state records.
   */
  function _testOfDuplicateStates() {
    $states = db_select('state_flow_states')
      ->fields('state_flow_states', array())
      ->execute()
      ->fetchAll();
    $hids = array();
    $duplicates = FALSE;
    foreach ($states as $state) {
      if (!empty($state->hid)) {
        if (empty($hids[$state->hid])) {
          $hids[$state->hid][] = $state;
        }
        else {
          $duplicates = TRUE;
        }
      }
    }
    $this
      ->assertFalse($duplicates, t('There are no duplicate records in State Flow States'));
    if ($duplicates) {
      debug($states);
    }
  }

}

/**
 * Tests for Workbench Moderation.
 */
class WorkbenchModerationBasicWebTestCase extends WorkbenchModerationWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Workbench Moderation basic tests',
      'description' => 'Perform basic web tests on Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

  /**
   * This test verifies that workflows are not used after being disabled.
   *
   * The test also sets the variable to ignore nodes that have no workflow set.
   *
   * The flow of this test is to
   * 1. Go to the node add page to verify that a workflow events are present.
   * 2. Disable the one workflow.
   * 3. Go back to the node add page to verify that no workflow events are present.
   */
  function testOfDisbablingWorkflow() {

    // Set the variable that will cause the ignore class to be picked up if no
    // other workflow is explicitly set.
    variable_set('workbench_workflows_default_to_ignore', TRUE);

    // Assert that workflow events are available.
    $this
      ->drupalGet("node/add/article");
    $this
      ->assertResponse(200);
    $xpath_string = "//select[@id=:select_id]";
    $xpath_replacements = array(
      ':select_id' => 'edit-event',
    );
    $tr = $this
      ->xpath($xpath_string, $xpath_replacements);
    $this
      ->assertEqual(count($tr), 1, 'There is a workflow available on the node add form.');

    // Go to the Workflows admin page and disable the only workflow.
    $this
      ->drupalGet("admin/config/workflow/workbench-workflows/workflows");
    $this
      ->assertResponse(200);

    // Click the disable link.
    $this
      ->clickLink('Disable');

    // Assert that workflow events are not available.
    $this
      ->drupalGet("node/add/article");
    $this
      ->assertResponse(200);
    $xpath_string = "//select[@id=:select_id]";
    $xpath_replacements = array(
      ':select_id' => 'edit-event',
    );
    $tr = $this
      ->xpath($xpath_string, $xpath_replacements);
    $this
      ->assertEqual(count($tr), 0, 'There is not workflow available on the node add form.');
  }

}
class WorkbenchModerationNodeAccessTestCase extends WorkbenchModerationWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Workbench Moderation Node Access tests',
      'description' => 'Perform node access with Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }
  public function setup() {
    parent::setup(func_get_args());
    $permissions = array(
      'view all content in state published',
    );
    $this->state_access_user = $this
      ->drupalCreateUser($permissions);
  }

  /**
   * Test access control to revisions.
   */
  function testPublishedRevisionAccess() {
    $edit = array();
    $init_title = $this
      ->randomName(8);
    $edit['title'] = $init_title;
    $edit['event'] = 'published';
    $edit['event_comment'] = $this
      ->randomName(8);
    $this
      ->drupalPost("node/add/article", $edit, t('Save'));
    $this
      ->drupalGet("node/1");
    $this
      ->assertText($init_title, t('Title is visible on draft node for logged in user.'));

    // Edit the node, creating a new title, set to needs_review, create new revision.
    $edit = array();
    $second_title = $this
      ->randomName(8);
    $edit['title'] = $second_title;
    $edit['event'] = 'needs_review';
    $edit['revision'] = 1;
    $this
      ->drupalPost("node/1/edit", $edit, t('Save'));

    // Edit the node, creating a new title, set to published, create new revision.
    $edit = array();
    $third_title = $this
      ->randomName(8);
    $edit['title'] = $third_title;
    $edit['event'] = 'published';
    $edit['revision'] = 1;
    $this
      ->drupalPost("node/1/edit", $edit, t('Save'));

    // Fetch revisions to provide information for development.
    $this
      ->drupalGet('node/1/revisions');

    // Active Published: 4
    // Published: 3
    // Needs Review: 2
    // Now we should have 2 published node revisions one of which is active.
    // Check access to different revisions.
    // Admin - has access to everything.
    $this
      ->drupalGet('node/1/revisions/3/view');
    $this
      ->assertResponse(200, 'Admin: Inactive published revision accessible');
    $this
      ->assertText($init_title);
    $this
      ->drupalGet('node/1/revisions/2/view');
    $this
      ->assertResponse(200, 'Admin: Needs review revision accessible');
    $this
      ->assertText($second_title);
    $this
      ->drupalGet('node/1/revisions/4/view');
    $this
      ->assertResponse(200, 'Admin: Active published revision accessible');
    $this
      ->assertText($third_title);

    // Anonymous - only can access the active published revision.
    $this
      ->drupalLogout();
    $this
      ->drupalGet('node/1/revisions/3/view');
    $this
      ->assertResponse(403, 'Anonymous: Inactive published revision inaccessible');
    $this
      ->assertNoTitle($init_title);
    $this
      ->drupalGet('node/1/revisions/2/view');
    $this
      ->assertResponse(403, 'Admin: Needs review revision inaccessible');
    $this
      ->assertNoTitle($second_title);
    $this
      ->drupalGet('node/1/revisions/4/view');
    $this
      ->assertResponse(200, 'Anonymous: Active published revision accessible');
    $this
      ->assertText($third_title);

    // User with explicit state access sees all published revisions. But can't
    // access revisions outside of that state.
    $this
      ->drupalLogin($this->state_access_user);
    $this
      ->drupalGet('node/1/revisions/3/view');
    $this
      ->assertResponse(200, 'Published-Access-User: Inactive published revision accessible');
    $this
      ->assertText($init_title);
    $this
      ->drupalGet('node/1/revisions/2/view');
    $this
      ->assertResponse(403, 'Published-Access-User: Needs review revision inaccessible');
    $this
      ->assertNoTitle($second_title);
    $this
      ->drupalGet('node/1/revisions/4/view');
    $this
      ->assertResponse(200, 'Published-Access-User: Active published revision accessible');
    $this
      ->assertText($third_title);
  }

}
class WorkbenchModerationModerateTabTestCase extends WorkbenchModerationWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Workbench Moderation Tabs tests',
      'description' => 'Perform Tabs tests for Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

  /**
   * Without the correct joins, there can be duplicates on the My Drafts tab.
   * This is a test of one of those instances.
   */
  function testMyDraftsTabDuplicates() {

    // Make a node, save as draft and change the state twice. This creates three
    // state_flow_history_entities for one node revision.
    $edit = array();
    $new_title = $this
      ->randomName(8);
    $edit['event'] = 'draft';
    $edit['title'] = $this
      ->randomName(8);
    $this
      ->drupalPost("node/add/article", $edit, t('Save'));
    $edit = array(
      'event' => 'needs_review',
    );

    // Go to needs review twice.
    $this
      ->drupalPost("node/1/revisions-state-flow-states", $edit, t('Update State'));
    $this
      ->drupalPost("node/1/revisions-state-flow-states", $edit, t('Update State'));

    // Check the my drafts tab.
    $this
      ->drupalGet("admin/workbench/drafts");
    $this
      ->assertResponse(200);
    $xpath_string = "//tbody/tr";
    $tr = $this
      ->xpath($xpath_string);
    $this
      ->assertEqual(count($tr), 1, 'There is only one row for the one existing revision');

    // Also check the needs review tab.
    $this
      ->drupalGet("admin/workbench/needs-review");
    $this
      ->assertResponse(200);
    $tr = $this
      ->xpath($xpath_string);
    $this
      ->assertEqual(count($tr), 1, 'There is only one row for the one existing revision');
  }

}
class WorkbenchModerationDraftTabTestCase extends WorkbenchModerationWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Workbench Draft Tab tests',
      'description' => 'Perform Draft Tab test for Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

  /**
   * Test View Draft tab.
   */
  public function testViewDraftTab() {

    // This first chunk is not specific to the draft tab and perhaps should be
    // abstracted to a helper function.
    $edit = array();
    $title = $this
      ->randomName(8);
    $edit['title'] = $title;
    $edit['event'] = 'draft';
    $edit['event_comment'] = $this
      ->randomName(8);
    $this
      ->drupalPost("node/add/article", $edit, t('Save'));
    $this
      ->drupalGet("node/1");
    $this
      ->assertText($title, t('Title is visible on draft node for logged in user.'));

    // Check for duplicate state records.
    $this
      ->_testOfDuplicateStates();

    // Check that view draft tab is not displaying.
    $this
      ->drupalGet('node/1/draft');
    $this
      ->assertResponse(403, 'View Draft tab responds with 403 to logged in user');

    // Check anonymous behavior. Verify access denied.
    $this
      ->drupalLogout();
    $this
      ->drupalGet("node/1");
    $this
      ->assertNoText($title, t('Title is not visible on draft node for anonymous user.'));
    $this
      ->assertResponse(403, 'Draft node page responds with 403 to anonymous user');

    // Check that view draft tab is not displaying.
    $this
      ->drupalGet('node/1/draft');
    $this
      ->assertResponse(403, 'View Draft tab responds with 403 to anonymous user');

    // Log in again.
    $web_user = $this
      ->drupalCreateUser(array(
      'administer nodes',
      'bypass node access',
      'administer content revisions',
    ));
    $this
      ->drupalLogin($web_user);

    // Set the node to published.
    $edit = array();
    $edit['event'] = 'published';
    $edit['event_comment'] = $this
      ->randomName(8);
    $this
      ->drupalPost("node/1/revisions-state-flow-states", $edit, t('Update State'));
    $this
      ->drupalGet("node/1");
    $this
      ->assertText($title, t('Title is visible on published node for logged in user.'));

    // Check for duplicate state records.
    $this
      ->_testOfDuplicateStates();

    // Check that view draft tab is not displaying.
    $this
      ->drupalGet('node/1/draft');
    $this
      ->assertResponse(403, 'View Draft tab responds with 403 to logged in user');

    // Check anonymous behavior. Verify access after publishing.
    $this
      ->drupalLogout();
    $this
      ->drupalGet("node/1");
    $this
      ->assertText($title, t('After publishing, anonymous user can see node title.'));
    $this
      ->assertResponse(200, 'After publishing,  anonymous user gets a 200 for node page.');

    // Check that view draft tab is not displaying.
    $this
      ->drupalGet('node/1/draft');
    $this
      ->assertResponse(403, 'View Draft tab responds with 403 to anonymous user');

    // Log in again.
    $web_user = $this
      ->drupalCreateUser(array(
      'administer nodes',
      'bypass node access',
      'administer content revisions',
    ));
    $this
      ->drupalLogin($web_user);

    // Edit the node, creating a new title, set to needs review.
    $edit = array();
    $new_title = $this
      ->randomName(8);
    $edit['title'] = $new_title;
    $edit['event'] = 'needs_review';
    $this
      ->drupalPost("node/1/edit", $edit, t('Save'));

    // Check for duplicate state records.
    $this
      ->_testOfDuplicateStates();

    // Check node/1.
    // Verify that it is still showing the old title.
    $this
      ->drupalGet("node/1");
    $this
      ->assertText($title, t('User can see published node title.'));
    $this
      ->assertResponse(200, 'User gets a 200 for node page.');

    // Check node/1/draft
    // Verify that it is showing the new draft title.
    $this
      ->drupalGet("node/1/draft");
    $this
      ->assertText($new_title, t('User can see node draft title.'));
    $this
      ->assertResponse(200, 'User gets a 200 for node draft page.');

    // Log out.
    // Check node/1.
    // Verify that it is still showing the old title to anonymous users.
    $this
      ->drupalLogout();
    $this
      ->drupalGet("node/1");
    $this
      ->assertText($title, t('Title is visible on published node for anonymous user.'));
    $this
      ->assertResponse(200, 'Anonymous user gets a 200 for node page.');

    // Check node/1/draft
    // Verify that gives an access denied.
    $this
      ->drupalGet("node/1/draft");
    $this
      ->assertNoText($new_title, t('Title is not visible on draft node for anonymous user.'));
    $this
      ->assertResponse(403, 'Draft node page responds with 403 to anonymous user');
  }

}
class WorkbenchModerationExternalNodeUpdateTestCase extends WorkbenchModerationWebTestCase {

  // Dummy for drafty.
  public static function getInfo() {
    return array(
      'name' => 'Workbench DUMMY tests',
      'description' => 'Perform WorkbenchModerationExternalNodeUpdateTestCase test for Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

}
class WorkbenchModerationFilesTestCase extends WorkbenchModerationWebTestCase {

  // Dummy for drafty.
  public static function getInfo() {
    return array(
      'name' => 'Workbench DUMMY tests',
      'description' => 'Perform WorkbenchModerationFilesTestCase test for Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

}
class WorkbenchModerationViewUnpublishedTestCase extends WorkbenchModerationWebTestCase {

  // Dummy for drafty.
  public static function getInfo() {
    return array(
      'name' => 'Workbench DUMMY tests',
      'description' => 'Perform WorkbenchModerationViewUnpublishedTestCase test for Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

}
class WorkbenchModerationPublishFromNodeFormTestCase extends WorkbenchModerationWebTestCase {

  // Dummy for drafty.
  public static function getInfo() {
    return array(
      'name' => 'Workbench DUMMY tests',
      'description' => 'Perform WorkbenchModerationPublishFromNodeFormTestCase test for Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

}
class WorkbenchModerationUnpublishTestCase extends WorkbenchModerationWebTestCase {

  // Dummy for drafty.
  public static function getInfo() {
    return array(
      'name' => 'Workbench DUMMY tests',
      'description' => 'Perform WorkbenchModerationUnpublishTestCase test for Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

}
class WorkbenchRedirectAfterTitleChangeTestCase extends WorkbenchModerationWebTestCase {

  // Dummy for drafty.
  public static function getInfo() {
    return array(
      'name' => 'Workbench DUMMY tests',
      'description' => 'Perform WorkbenchRedirectAfterTitleChangeTestCase test for Workbench Moderation.',
      'group' => 'Workbench Moderation',
    );
  }

}