You are here

cas.test in CAS 6.3

Same filename and directory in other branches
  1. 7 cas.test

Tests for cas.module.

File

cas.test
View source
<?php

/**
 * @file
 * Tests for cas.module.
 */
class CasTestHelper extends DrupalWebTestCase {
  protected $admin_user;

  /**
   * Helper class for CAS tests.
   *
   * Creates an administrative user and downloads phpCAS.
   */
  function setUp() {

    // Install modules needed for this test. This could have been passed in as
    // either a single array argument or a variable number of string arguments.
    // @todo Remove this compatibility layer in Drupal 8, and only accept
    // $modules as a single array argument.
    $modules = func_get_args();
    if (isset($modules[0]) && is_array($modules[0])) {
      $modules = $modules[0];
    }

    // cas_test requires the CAS Server module.
    $modules = array_merge(array(
      'cas',
      'cas_test',
      'cas_server',
    ), $modules);
    parent::setUp($modules);

    // Tests will fail unless clean URLs are enabled, due to an incompatibility
    // in phpCAS.
    variable_set('clean_url', TRUE);

    // Create admin user.
    $this->admin_user = $this
      ->drupalCreateUser(array(
      'administer users',
      'administer cas',
    ));

    // Download and extract in PHPCAS.
    $this
      ->downloadExtractPhpCas('1.3.1');
  }

  /**
   * Download and extract phpCAS.
   *
   * Sets the 'cas_library_dir' variable to the directory where phpCAS
   * is downloaded.
   *
   * @param $version
   *   The phpCAS version number to download and extract.
   */
  function downloadExtractPhpCas($version) {

    // Find the most URL of the most recent phpCAS version.
    $directory = 'CAS-' . $version;
    $filename = 'CAS-' . $version . '.tgz';
    $url = 'http://downloads.jasig.org/cas-clients/php/' . $version . '/' . $filename;

    // Avoid downloading the file dozens of times
    $simpletest_cache = $this->originalFileDirectory . '/simpletest/cas';
    if (!file_exists($simpletest_cache)) {
      mkdir($simpletest_cache);
    }

    // Local archive name.
    $local_archive = $simpletest_cache . '/' . $filename;
    $cas_library_dir = $simpletest_cache . '/' . $directory;

    // Begin single threaded code.
    if (function_exists('sem_get')) {
      $semaphore = sem_get(ftok(__FILE__, 1));
      sem_acquire($semaphore);
    }

    // Download and extact the archive, but only in one thread.
    if (!file_exists($local_archive)) {
      $result = drupal_http_request($url);
      file_put_contents($local_archive, $result->data);
    }
    if (!file_exists($cas_library_dir)) {

      // Get Archive_Tar. @see http://drupal.org/node/1113618.
      $archive_tar = $simpletest_cache . '/archive_tar.inc';
      $result = drupal_http_request('http://drupal.org/files/issues/system.tar_.inc_.txt');
      file_put_contents($archive_tar, $result->data);
      include_once $archive_tar;

      // Extract the files.
      $archiver = new Archive_Tar($local_archive);
      $archiver
        ->extract($simpletest_cache);
    }
    if (function_exists('sem_get')) {
      sem_release($semaphore);
    }

    // End single threaded code.
    // Verify that files were successfully extracted.
    $this
      ->assertTrue(file_exists($cas_library_dir . '/CAS.php'), t('CAS.php found in @cas_library_dir.', array(
      '@cas_library_dir' => $cas_library_dir,
    )));

    // Set the CAS library directory.
    variable_set('cas_library_dir', $cas_library_dir);
  }

  /**
   * Create a CAS user with the specified username.
   *
   * @param $cas_name
   *   The CAS username. If omitted, a CAS username will be automatically
   *   generated.
   * @param $permissions
   *   An array of permissions to assign to the created user.
   *
   * @return
   *   A user account object. The CAS username is present in the cas_name
   *   field.
   */
  function casCreateUser($cas_name = NULL, $permissions = array(
    'access comments',
    'access content',
    'post comments',
    'post comments without approval',
  )) {

    // Create user.
    $account = $this
      ->drupalCreateUser($permissions);
    $pass_raw = $account->pass_raw;

    // Add CAS username.
    if (empty($cas_name)) {
      $cas_name = $this
        ->randomName();
    }
    $edit['cas_name'] = $cas_name;
    $account = user_save($account, $edit);

    // Restore password.
    $account->pass_raw = $pass_raw;
    return $account;
  }

  /**
   * Log in a CAS user with the internal browser.
   *
   * @param $account
   *   A user object with a valid CAS username field, or the CAS username as a
   *   string.
   * @param $attributes
   *   Additional attributes for the CAS user.
   */
  function casLogin($account, $attributes = array()) {
    if ($this->loggedInUser) {
      $this
        ->drupalLogout();
    }

    // Log in the user.
    $cas_name = $this
      ->setCasUser($account, $attributes);
    $this
      ->drupalGet('cas');
    $pass = $this
      ->assertLink(t('Log out'), 0, t('CAS user %cas_name successfully logged in.', array(
      '%cas_name' => $cas_name,
    )), t('User login'));
    if ($pass) {
      $this->loggedInUser = cas_user_load_by_name($cas_name, TRUE);
    }
  }

  /**
   * Set the CAS username and attributes for the next CAS login request.
   *
   * @param $account
   *   A user object with a valid CAS username field, or the CAS username as a
   *   string.
   * @param $attributes
   *   Additional attributes for the CAS user.
   *
   * @return
   *   The CAS username.
   */
  function setCasUser($account, $attributes = array()) {
    $cas_name = is_object($account) ? $account->cas_name : $account;
    $cas_user = array(
      'name' => $cas_name,
      'attributes' => $attributes,
    );
    variable_set('cas_test_cas_user', $cas_user);
    return $cas_name;
  }

  /**
   * Clear the CAS username and attributes for the next CAS login request.
   */
  function clearCasUser() {
    variable_del('cas_test_cas_user');
  }

  /**
   * Assert that the user has logged in.
   *
   * @return
   *  TRUE if the assertion succeeded, FALSE otherwise.
   */
  function assertLoggedIn($account) {
    $pass = $this
      ->assertLink(t('Log out'), 0, t('CAS user %cas_name successfully logged in.', array(
      '%cas_name' => $account->cas_name,
    )), t('User login'));
    if ($pass) {
      $this->loggedInUser = $account;
    }
    return $pass;
  }

  /**
   * Assert that the user has been logged out.
   *
   * @return
   *  TRUE if the assertion succeeded, FALSE otherwise.
   */
  function assertLoggedOut() {
    $this
      ->drupalGet('user');
    $pass = $this
      ->assertField('name', t('Username field found.'), t('Logout'));
    $pass = $pass && $this
      ->assertField('pass', t('Password field found.'), t('Logout'));
    if ($pass) {
      $this->loggedInUser = FALSE;
    }
    return $pass;
  }

  /**
   * Assert the value of the token.
   *
   * @param $token
   *   A token to evaluate for the current CAS user.
   * @param $value
   *   The expected value after the token is evaluated.
   * @param $message
   *   The message to display along with the assertion.
   *
   * @return
   *  TRUE if the assertion succeeded, FALSE otherwise.
   */
  function assertToken($token, $value, $message = '') {
    $options = array(
      'query' => array(
        'token' => $token,
        'name' => $this->loggedInUser->cas_name,
      ),
    );
    $path = 'cas_test/token';
    $out = $this
      ->drupalGet($path, $options);
    return $this
      ->assertEqual($out, $value, $message, 'Token');
  }

}
class CasUserAdminTestCase extends CasTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'User administration',
      'description' => 'Test CAS user administration.',
      'group' => 'Central Authentication Service',
    );
  }

  /**
   * Registers, modifies, and deletes a CAS user using User API hooks.
   */
  function testCASUserHooks() {

    // Create a test account.
    $account = $this
      ->drupalCreateUser();
    $uid = $account->uid;

    // Add a CAS username.
    $cas_name = $this
      ->randomName();
    $edit = array(
      'cas_name' => $cas_name,
    );
    $account = user_save($account, $edit);
    $this
      ->assertEqual($cas_name, $account->cas_name, t('CAS username %cas_name successfully created.', array(
      '%cas_name' => $cas_name,
    )));

    // Reload the account and ensure the CAS name is still present.
    $account = user_load($uid);
    $this
      ->assertEqual($cas_name, $account->cas_name, t('CAS username %cas_name successfully saved.', array(
      '%cas_name' => $cas_name,
    )));

    // Load the account by the CAS username.
    $account = cas_user_load_by_name($cas_name);
    $this
      ->assertEqual($uid, $account->uid, t('Loaded the correct account with CAS username %cas_name.', array(
      '%cas_name' => $cas_name,
    )));

    // Change the CAS username.
    $cas_new_name = $this
      ->randomName();
    $account = user_load($uid);
    $edit = array(
      'cas_name' => $cas_new_name,
    );
    user_save($account, $edit);
    $account = user_load($uid);
    $this
      ->assertEqual($cas_new_name, $account->cas_name, t('CAS username %cas_name successfully updated.', array(
      '%cas_name' => $cas_new_name,
    )));
    $this
      ->assertEqual(count($account->cas_names), 1, t('Only one CAS username is present.'));
    $account = cas_user_load_by_name($cas_name);
    $this
      ->assertFalse($account, t('Could not load account using old CAS username.'));

    // Remove the CAS username.
    $account = user_load($uid);
    $edit = array(
      'cas_name' => NULL,
    );
    user_save($account, $edit);
    $account = user_load($uid);
    $this
      ->assertFalse($account->cas_name, t('CAS username successfully deleted.'));
    $this
      ->assertEqual(count($account->cas_names), 0, t('No CAS usernames are present.'));

    // Attempt to load by a non-existant CAS username.
    $account = cas_user_load_by_name($cas_new_name);
    $this
      ->assertFalse($account, t('Could not load account with non-existent CAS username.'));

    // Verify that all CAS usernames have been removed from {cas_user}.
    $cas_uid_count = db_result(db_query("SELECT COUNT(*) FROM {cas_user} WHERE cas_name IN ('%s', '%s')", $cas_name, $cas_new_name));
    $this
      ->assertEqual($cas_uid_count, 0, t('CAS usernames successfully removed from {cas_user}.'));
  }

  /**
   * Tests adding a user with a CAS username in the administrative interface.
   */
  function testUserAdd() {
    $this
      ->drupalLogin($this->admin_user);

    // Register a user with a CAS username.
    $cas_name = $this
      ->randomName();
    $edit = array(
      'name' => $this
        ->randomName(),
      'mail' => $this
        ->randomName() . '@example.com',
      'cas_name' => $cas_name,
      'pass[pass1]' => $pass = $this
        ->randomString(),
      'pass[pass2]' => $pass,
      'notify' => FALSE,
    );
    $this
      ->drupalPost('admin/user/user/create', $edit, t('Create new account'));
    $this
      ->assertText(t('Created a new user account for @name. No e-mail has been sent.', array(
      '@name' => $edit['name'],
    )), 'User created');
    $this
      ->drupalGet('admin/user/user');
    $this
      ->assertText($edit['name'], 'User found in list of users');
    $this
      ->assertText($edit['cas_name'], 'CAS username found in list of users');

    // Verify that duplicate CAS usernames are not allowed.
    $edit = array(
      'name' => $this
        ->randomName(),
      'mail' => $this
        ->randomName() . '@example.com',
      'cas_name' => $cas_name,
      'pass[pass1]' => $pass = $this
        ->randomString(),
      'pass[pass2]' => $pass,
      'notify' => FALSE,
    );
    $this
      ->drupalPost('admin/user/user/create', $edit, t('Create new account'));
    $this
      ->assertText(t('The CAS username is already in use on this site.'), 'CAS username already in use.');
  }

  /**
   * Tests adding a CAS user in the administrative interface.
   */
  function testCasUserAdd() {
    $this
      ->drupalLogin($this->admin_user);

    // Add a CAS user.
    $edit = array(
      'cas_name' => $this
        ->randomName(),
    );
    $this
      ->drupalPost('admin/user/user/cas/create', $edit, t('Create new account'));
    $this
      ->assertText(t('Created a new user account for @name. No e-mail has been sent.', array(
      '@name' => $edit['cas_name'],
    )), 'User created');

    // Verify the user shows up in the list of all users.
    $this
      ->drupalGet('admin/user/user');
    $this
      ->assertNoUniqueText($edit['cas_name'], 'User and CAS username found in list of users');

    // Attempt to add the user again and see that it fails.
    $this
      ->drupalPost('admin/user/user/cas/create', $edit, t('Create new account'));
    $this
      ->assertText(t('The CAS username is already in use on this site.'), 'CAS username already in use.');
  }

}

/**
 * Test case to test user editing behavior.
 */
class CasUserTestCase extends CasTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'User behavior',
      'description' => 'Test CAS user behavior, including auto-registration and user editing.',
      'group' => 'Central Authentication Service',
    );
  }

  /**
   * Tests automatically registering a user on login.
   */
  function testCasAutoRegister() {
    $cas_name = $this
      ->randomName();
    $this
      ->setCasUser($cas_name);

    // Test that the user is not automatically registered.
    variable_set('cas_user_register', FALSE);
    $this
      ->drupalGet('cas');
    $this
      ->assertRaw(t('No account found for %cas_name.', array(
      '%cas_name' => $cas_name,
    )));

    // Test that the user is automatically registered.
    variable_set('cas_user_register', TRUE);
    $this
      ->drupalGet('cas');
    $this->loggedInUser = cas_user_load_by_name($cas_name, TRUE);
    $this
      ->assertRaw(t('Logged in via CAS as %cas_username.', array(
      '%cas_username' => $cas_name,
    )));
    $this
      ->drupalLogout();

    // Create a new user.
    $user2 = $this
      ->drupalCreateUser();
    $cas_name = $user2->name;
    $this
      ->setCasUser($cas_name);

    // Test that CAS does not hijack an existing username.
    $this
      ->drupalGet('cas');
    $this
      ->assertRaw(t('A new account could not be created for %cas_name. The username is already in use on this site.', array(
      '%cas_name' => $cas_name,
    )));
  }
  function testUserEdit() {
    $cas_name = $this
      ->randomName();
    $account = $this
      ->casCreateUser($cas_name, array(
      'change own username',
    ));
    $this
      ->casLogin($cas_name);

    // Standard user page.
    variable_set('cas_hide_email', FALSE);
    variable_set('cas_hide_password', FALSE);
    $this
      ->drupalGet("user/{$account->uid}/edit");
    $this
      ->assertField('mail', 'E-mail field is present.');
    $this
      ->assertField('pass[pass1]', 'Existing password field 1 is present.');
    $this
      ->assertField('pass[pass2]', 'Existing password field 2 is present.');
    $edit = array(
      'mail' => $mail = $this
        ->randomName() . '@example.com',
    );
    $this
      ->drupalPost("user/{$account->uid}/edit", $edit, t('Save'));
    $this
      ->assertFieldByName('mail', $mail);

    // Hide the password, ensure edits can be made..
    variable_set('cas_hide_password', TRUE);
    $this
      ->drupalGet("user/{$account->uid}/edit");
    $this
      ->assertNoField('pass[pass1]', 'Existing password field 1 is not present.');
    $this
      ->assertNoField('pass[pass2]', 'Existing password field 2 is not present.');
    $edit = array(
      'mail' => $mail = $this
        ->randomName() . '@example.com',
    );
    $this
      ->drupalPost("user/{$account->uid}/edit", $edit, t('Save'));
    $this
      ->assertFieldByName('mail', $mail);

    // Hide the e-mail field as well, ensure that it is not visible.
    variable_set('cas_hide_email', TRUE);
    $this
      ->drupalGet("user/{$account->uid}/edit");

    // @todo: Need to test that the mail is field is hidden.
    // $this->assertNoField('mail', 'E-mail field is not present.');
  }
  function testCaseInsensitiveLogin() {
    $account = $this
      ->casCreateUser();
    $this
      ->casLogin(strtoupper($account->cas_name));
    $this
      ->assertLoggedIn($account);
  }

}

// Detect if we're running on Drupal.org's automated testbot.
if (!file_exists("../checkout")) {

  // @todo:
  // Re-enable these test cases when we have a way of telling qa.drupal.org
  // about the (soft) dependency on the token module.

  /**
   * Tests integration with token.
   */
  class CasTokenTestCase extends CasTestHelper {
    public static function getInfo() {
      return array(
        'name' => 'CAS Token',
        'description' => 'Tests CAS token replacement.',
        'group' => 'Central Authentication Service',
      );
    }
    function setUp() {
      parent::setUp(array(
        'token',
      ));
    }

    /**
     * Tests that the CAS username is available by a token.
     */
    function testNameToken() {
      $account = $this
        ->casCreateUser();
      $this
        ->casLogin($account);
      $this
        ->assertToken('[cas-name]', $account->cas_name);
      $this
        ->assertToken('[cas-name-raw]', $account->cas_name);
    }

  }
}

/**
 * Test case to test user logout behavior.
 */
class CasLogoutRedirectionTestCase extends CasTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'Logout redirection',
      'description' => 'Test CAS user logout redirection.',
      'group' => 'Central Authentication Service',
    );
  }

  /**
   * Test redirection on user logout.
   */
  function testLogoutRedirection() {
    $account = $this
      ->casCreateUser();
    $this
      ->casLogin($account);
    $this
      ->drupalGet('caslogout');
    $this
      ->assertText('Logged out. No redirection provided.');
    $this
      ->assertLoggedOut();

    // Verify the destination parameter may be passed on logout, i.e.,
    // caslogout?destination=node
    $destination = 'node';
    $this
      ->casLogin($account);
    $this
      ->drupalGet('caslogout', array(
      'query' => array(
        'destination' => $destination,
      ),
    ));
    $this
      ->assertText(t('Logged out. Continue to @url.', array(
      '@url' => url($destination, array(
        'absolute' => TRUE,
      )),
    )));
    $this
      ->assertLoggedOut();

    // Verify that remote destination parameters are not allowed.
    $destination = 'http://example.com/?query=yes#fragment';
    $this
      ->casLogin($account);
    $this
      ->drupalGet('caslogout', array(
      'query' => array(
        'destination' => $destination,
      ),
    ));
    $this
      ->assertText(t('Logged out. No redirection provided.'));
    $this
      ->assertLoggedOut();

    // Verify 'cas_logout_destination' works for a variety of destinations,
    // including remote destinations.
    $destinations = array(
      '<front>',
      'http://example.com/?query=yes#fragment',
      'node/1',
    );
    foreach ($destinations as $destination) {
      variable_set('cas_logout_destination', $destination);
      $this
        ->casLogin($account);
      $this
        ->drupalGet('caslogout');
      $this
        ->assertText(t('Logged out. Continue to @url.', array(
        '@url' => url($destination, array(
          'absolute' => TRUE,
        )),
      )));
      $this
        ->assertLoggedOut();
    }

    // Verify 'cas_logout_destination' can be overwritten by passing the
    // destination query string.
    variable_set('cas_logout_destination', 'http://example.com/');
    $destination = 'node/1';
    $this
      ->casLogin($account);
    $this
      ->drupalGet('caslogout', array(
      'query' => array(
        'destination' => $destination,
      ),
    ));
    $this
      ->assertText(t('Logged out. Continue to @url.', array(
      '@url' => url($destination, array(
        'absolute' => TRUE,
      )),
    )));
    $this
      ->assertLoggedOut();
  }

}

/**
 * Test case to test user login behavior.
 */
class CasLoginRedirectionTestCase extends CasTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'Login redirection',
      'description' => 'Test CAS user login redirection.',
      'group' => 'Central Authentication Service',
    );
  }

  /**
   * Verify login redirection for an existing user.
   */
  function testExistingUserLoginRedirection() {
    $node1 = $this
      ->drupalCreateNode();
    $node2 = $this
      ->drupalCreateNode();
    $node3 = $this
      ->drupalCreateNode();

    // Create a CAS user.
    $account = $this
      ->casCreateUser();
    $cas_name = $account->cas_name;
    $this
      ->setCasUser($cas_name);

    // Test going to 'cas'
    $this
      ->drupalGet('cas');
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl('');
    $this
      ->drupalLogout();

    // Test going to 'cas?destination=node/$node1->nid'
    $destination = "node/{$node1->nid}";
    $this
      ->drupalGet('cas', array(
      'query' => array(
        'destination' => $destination,
      ),
    ));
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl($destination);
    $this
      ->drupalLogout();

    // Use the login block on $node2.
    $destination = "node/{$node2->nid}";
    variable_set('cas_login_form', CAS_ADD_LINK);
    $edit = array(
      'cas_identifier' => TRUE,
    );
    $this
      ->drupalPost($destination, $edit, t('Log in'));
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl($destination);
    $this
      ->drupalLogout();

    // Use the regular login page, without a destination.
    $edit = array(
      'cas_identifier' => TRUE,
    );
    $this
      ->drupalPost('user/login', $edit, t('Log in'));
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl('user');
    $this
      ->drupalLogout();

    // Use the regular login page, with a destination.
    $destination = "node/{$node3->nid}";
    $edit = array(
      'cas_identifier' => TRUE,
    );
    $this
      ->drupalPost('user/login', $edit, t('Log in'), array(
      'query' => array(
        'destination' => $destination,
      ),
    ));
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl($destination);
    $this
      ->drupalLogout();

    // External destinations are not allowed.
    $destination = '';
    $this
      ->drupalGet('cas', array(
      'query' => array(
        'destination' => 'http://example.com/node/3',
      ),
    ));
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl($destination);
    $this
      ->drupalLogout();
  }

  /**
   * Verify login redirection for a new user.
   */
  function testNewUserLoginRedirection() {

    // Initial login without a destination goes to front page.
    $cas_name = $this
      ->randomName();
    $this
      ->casLogin($cas_name);
    $this
      ->assertUrl('');
    $this
      ->drupalLogout();

    // Initial login with redirection goes to specified destination.
    $node = $this
      ->drupalCreateNode();
    variable_set('cas_first_login_destination', "node/{$node->nid}");
    $cas_name = $this
      ->randomName();
    $account = $this
      ->casLogin($cas_name);
    $this
      ->assertUrl("node/{$node->nid}", array(
      'query' => array(
        'destination' => '',
      ),
    ));
    $this
      ->drupalLogout();

    // The second login should not be redirected.
    $this
      ->casLogin($cas_name);
    $this
      ->assertUrl('');
    $this
      ->drupalLogout();

    // Initial login with a admin-created account goes to the specified
    // destination.
    $account = $this
      ->casCreateUser();
    $this
      ->casLogin($account);
    $this
      ->assertUrl("node/{$node->nid}", array(
      'query' => array(
        'destination' => '',
      ),
    ));
    $this
      ->drupalLogout();

    // The second login should not be redirected.
    $this
      ->casLogin($account);
    $this
      ->assertUrl('');
    $this
      ->drupalLogout();
  }

}

/**
 * Test CAS Single Sign-Out.
 */
class CasSingleSignOutTestCase extends CasTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'Single Sign-Out',
      'description' => 'Test CAS Single Sign-Out.',
      'group' => 'Central Authentication Service',
    );
  }
  function testSingleSignOut() {

    // Create a user, and log in.
    $cas_name = $this
      ->randomName();
    $account = $this
      ->casCreateUser($cas_name);
    $this
      ->casLogin($account);
    cas_test_single_sign_out($cas_name);
    $this
      ->assertLoggedOut();

    // @todo: Add additional tests for other methods of logging in (especially
    //   methods coming from cas_pages).
  }
  function testSingleSignOutDoubleEncode() {

    // Create a user, and log in.
    $cas_name = $this
      ->randomName();
    $account = $this
      ->casCreateUser($cas_name);
    $this
      ->casLogin($account);
    cas_test_single_sign_out($cas_name, TRUE);
    $this
      ->assertLoggedOut();

    // @todo: Add additional tests for other methods of logging in (especially
    //   methods coming from cas_pages).
  }

}

/**
 * Test case for CAS gateway feature.
 */
class CasGatewayTestCase extends CasTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'CAS Gateway',
      'description' => 'Test CAS Gateway ("Check to see if user is already logged in") feature.',
      'group' => 'Central Authentication Service',
    );
  }
  function setUp() {
    parent::setUp();
    variable_set('cas_check_first', TRUE);
  }

  /**
   * Test the CAS Gateway functionality of the user is not logged in.
   */
  function testCasGatewayLoggedOut() {
    $this
      ->drupalGet('');
    $this
      ->assertTrue($this->redirect_count > 1, 'Polled CAS server on first request.');
    $this
      ->drupalGet('');
    $this
      ->assertEqual($this->redirect_count, 0, 'Did not poll CAS server on second request.');
    $this
      ->drupalGet('node');
    $this
      ->assertEqual($this->redirect_count, 0, 'Did not poll CAS server on third request.');
  }

  /**
   * Test the CAS Gateway functionality of the user is logged in.
   */
  function testCasGatewayLoggedIn() {

    // Create a user.
    $cas_name = $this
      ->randomName();
    $account = $this
      ->casCreateUser($cas_name);
    $this
      ->setCasUser($cas_name);
    $this
      ->drupalGet('node');
    $this
      ->assertLoggedIn($account);
  }

}

/**
 * Test case for CAS force login feature.
 */
class CasRequiredLoginTestCase extends CasTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'Required Login',
      'description' => 'Test CAS required login redirection.',
      'group' => 'Central Authentication Service',
    );
  }

  /**
   * Test redirection forced by cas_access and cas_pages variables.
   */
  function testCasPages() {
    $node1 = $this
      ->drupalCreateNode();
    $node2 = $this
      ->drupalCreateNode();
    $account = $this
      ->casCreateUser();
    $this
      ->setCasUser($account);
    $this
      ->drupalGet("node/{$node2->nid}");

    // Enable required login for $node.
    variable_set('cas_access', 0);
    variable_set('cas_pages', "node/{$node1->nid}\nnode/{$node2->nid}");

    // Visit the node and verify we are logged in.
    $this
      ->drupalGet("node/{$node2->nid}");
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl("node/{$node2->nid}");
    $this
      ->drupalLogout();

    // Invert the access restrictions. Verify we can get the access the node
    // without restriction.
    variable_set('cas_access', 1);
    $this
      ->drupalGet("node/{$node1->nid}");
    $this
      ->assertField('name', t('Username field found.'), t('Logout'));
    $this
      ->assertField('pass', t('Password field found.'), t('Logout'));

    // Verify that accessing any other page redirects to the login page.
    $this
      ->clearCasUser();
    $this
      ->drupalGet('node');
    $this
      ->assertText('No CAS name provided.');
  }

  /**
   * Test redirection prevented by cas_exclude.
   */
  function testCasExclude() {
    $node = $this
      ->drupalCreateNode();
    $account = $this
      ->casCreateUser();
    $this
      ->setCasUser($account);
    variable_set('cas_check_first', TRUE);
    variable_set('cas_exclude', "node/{$node->nid}");

    // Visit an excluded page and ensure we did not try to log in.
    $this
      ->drupalGet("node/{$node->nid}");
    $this
      ->assertField('name', t('Username field found.'), t('Logout'));
    $this
      ->assertField('pass', t('Password field found.'), t('Logout'));

    // Visit another page and ensure we logged in.
    $this
      ->drupalGet('node');
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl('node');
  }

}

/**
 * Tests the visibility and functionality of the CAS login block.
 */
class CasLoginBlockTestCase extends CasTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'CAS login block',
      'description' => 'Tests the CAS login block.',
      'group' => 'Central Authentication Service',
    );
  }
  function setUp() {
    parent::setUp();

    // Enable the CAS login block.
    $admin_user = $this
      ->drupalCreateUser(array(
      'administer blocks',
    ));
    $this
      ->drupalLogin($admin_user);
    $edit = array(
      'user_0[region]' => '-1',
      'cas_0[region]' => 'left',
    );
    $this
      ->drupalPost('admin/build/block', $edit, t('Save blocks'));
    $this
      ->drupalLogout();
  }

  /**
   * Asserts that the CAS login block is shown or not shown.
   *
   * @param $visible
   *   Whether or not the CAS login block is expected to be shown.
   *
   * @return
   *  TRUE if the assertion succeeded, FALSE otherwise.
   */
  function assertCasLoginBlock($visible) {
    $xpath = '//div[@id=block-cas-0]/*';
    $xpath = $this
      ->buildXPathQuery('//div[@id=:id]/*', array(
      ':id' => 'block-cas-0',
    ));
    if ($visible) {
      return $this
        ->assertFieldByXPath($xpath, NULL, t('CAS login block found.'));
    }
    else {
      return $this
        ->assertNoFieldByXPath($xpath, NULL, t('CAS login block not found.'));
    }
  }

  /**
   * Tests the visibility and functionality of the CAS login block.
   */
  function testCasLoginBlock() {
    $account = $this
      ->casCreateUser();
    $this
      ->setCasUser($account);

    // Verify that the block is shown on some pages, but not on others.
    $this
      ->drupalGet('');
    $this
      ->assertCasLoginBlock(TRUE);
    $this
      ->drupalGet('user');
    $this
      ->assertCasLoginBlock(FALSE);
    $this
      ->drupalGet('user/1');
    $this
      ->assertCasLoginBlock(TRUE);

    // Log in using the login block, and verify redirection works.
    $edit = array();
    $submit = t(variable_get('cas_login_invite', CAS_LOGIN_INVITE_DEFAULT));
    $this
      ->drupalPost('', $edit, $submit);
    $this
      ->assertLoggedIn($account);
    $this
      ->assertUrl('node');

    // Block should not be shown to logged in users.
    $this
      ->assertCasLoginBlock(FALSE);
  }

}

Classes

Namesort descending Description
CasGatewayTestCase Test case for CAS gateway feature.
CasLoginBlockTestCase Tests the visibility and functionality of the CAS login block.
CasLoginRedirectionTestCase Test case to test user login behavior.
CasLogoutRedirectionTestCase Test case to test user logout behavior.
CasRequiredLoginTestCase Test case for CAS force login feature.
CasSingleSignOutTestCase Test CAS Single Sign-Out.
CasTestHelper @file Tests for cas.module.
CasUserAdminTestCase
CasUserTestCase Test case to test user editing behavior.