You are here

simple_ldap_user.test in Simple LDAP 7.2

Same filename and directory in other branches
  1. 7 simple_ldap_user/simple_ldap_user.test

Tests for Simple LDAP User module.

File

simple_ldap_user/simple_ldap_user.test
View source
<?php

/**
 * @file
 * Tests for Simple LDAP User module.
 */
abstract class SimpleLdapUserTestCase extends SimpleLdapServerTestCase {
  protected $drupalUser;
  protected $ldapUser;
  protected $userPassword;

  /**
   * Inherited parent::setUp().
   */
  public function setUp() {

    // Get the live simple_ldap_user configuration.
    $basedn = simple_ldap_user_variable_get('simple_ldap_user_basedn');
    $scope = simple_ldap_user_variable_get('simple_ldap_user_scope');
    $objectclass = simple_ldap_user_variable_get('simple_ldap_user_objectclass');
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');
    $attribute_mail = simple_ldap_user_variable_get('simple_ldap_user_attribute_mail');
    $attribute_pass = simple_ldap_user_variable_get('simple_ldap_user_attribute_pass');
    $attribute_rdn = simple_ldap_user_variable_get('simple_ldap_user_attribute_rdn');
    $attribute_map = simple_ldap_user_variable_get('simple_ldap_user_attribute_map');
    $password_hash = simple_ldap_user_variable_get('simple_ldap_user_password_hash');
    $filter = simple_ldap_user_variable_get('simple_ldap_user_filter');
    $source = simple_ldap_user_variable_get('simple_ldap_user_source');
    $sync = simple_ldap_user_variable_get('simple_ldap_user_sync');
    $delete_ldap_user = simple_ldap_user_variable_get('simple_ldap_user_delete_from_ldap');

    // Make sure the variables from settings.php are written to the database.
    // Otherwise subsequent tests will not be able to read them. These are
    // cleaned up in $this->tearDown().
    variable_set('simple_ldap_user_attribute_map', $attribute_map);

    // Create the simpletest sandbox.
    $modules = func_get_args();
    if (isset($modules[0]) && is_array($modules[0])) {
      $modules = $modules[0];
    }
    parent::setUp($modules);

    // Initialize an LDAP server object.
    $server = SimpleLdapServer::singleton();

    // Create a set of drupal-only users before enabling Simple LDAP User so
    // that they are only present in Drupal.
    for ($i = 0; $i < 5; $i++) {
      $this->drupalUser[$i] = $this
        ->drupalCreateUser();
    }

    // Get a list of required attributes for the configured objectclass(es).
    $must = array();
    foreach ($objectclass as $o) {
      foreach ($server->schema
        ->must($o, TRUE) as $m) {
        if (!in_array($m, $must)) {
          $must[] = strtolower($m);
        }
      }
    }

    // Add mapped fields to user entity.
    foreach ($attribute_map as $attribute) {

      // Clean up the attribute. We can't use simple_ldap_user_variable_get()
      // yet because simple_ldap_user is not enabled yet. The module can't be
      // enabled until after the Drupal users are initialized, or they would
      // sync to LDAP, and invalidate the tests. Chicken and egg problem here.
      $attribute['ldap'] = strtolower($attribute['ldap']);
      if (!is_array($attribute['drupal'])) {
        $attribute['drupal'] = array(
          $attribute['drupal'],
        );
      }

      // Skip one-to-many mappings.
      if (count($attribute['drupal']) > 1) {
        continue;
      }

      // Get the drupal name and type.
      $drupal_attribute = reset($attribute['drupal']);
      $type = substr($drupal_attribute, 0, 1);

      // Create user fields.
      if ($type == '#') {
        $drupal_attribute = substr($drupal_attribute, 1);
        $required = in_array($attribute['ldap'], $must);
        $attributetype = $server->schema
          ->get('attributetypes', $attribute['ldap']);

        // A syntax type of 1.3.6.1.4.1.1466.115.121.1.27 is an integer.
        if (isset($attributetype['syntax']) && $attributetype['syntax'] == '1.3.6.1.4.1.1466.115.121.1.27') {
          $type = 'number_integer';
        }
        else {
          $type = 'text';
        }
        field_create_field(array(
          'field_name' => $drupal_attribute,
          'type' => $type,
          'cardinality' => 1,
        ));
        field_create_instance(array(
          'field_name' => $drupal_attribute,
          'entity_type' => 'user',
          'label' => $drupal_attribute,
          'bundle' => 'user',
          'required' => $required,
          'settings' => array(
            'user_register_form' => $required,
          ),
        ));

        // Populate the field value of each of the test Drupal users.
        foreach ($this->drupalUser as $drupal_user) {
          if ($type == 'number_integer') {
            $edit[$drupal_attribute]['und'][0]['value'] = $drupal_user->uid + 1000;
          }
          else {
            $edit[$drupal_attribute]['und'][0]['value'] = $this
              ->randomName();
          }
          $drupal_user = user_save($drupal_user, $edit);
        }
      }
    }

    // Enable the Simple LDAP User module.
    $modules = array(
      'simple_ldap_user',
    );
    $success = module_enable($modules);
    $this
      ->assertTrue($success, t('Enabled modules: %modules', array(
      '%modules' => implode(', ', $modules),
    )));

    // Configure the sandboxed simple_ldap_user.
    variable_set('simple_ldap_user_basedn', $basedn);
    variable_set('simple_ldap_user_scope', $scope);
    variable_set('simple_ldap_user_objectclass', $objectclass);
    variable_set('simple_ldap_user_attribute_name', $attribute_name);
    variable_set('simple_ldap_user_attribute_mail', $attribute_mail);
    variable_set('simple_ldap_user_attribute_pass', $attribute_pass);
    variable_set('simple_ldap_user_attribute_rdn', $attribute_rdn);
    variable_set('simple_ldap_user_attribute_map', $attribute_map);
    variable_set('simple_ldap_user_password_hash', $password_hash);
    variable_set('simple_ldap_user_filter', $filter);
    variable_set('simple_ldap_user_source', $source);
    variable_set('simple_ldap_user_sync', $sync);
    variable_set('simple_ldap_user_delete_from_ldap', $delete_ldap_user);

    // Get the fully qualified attribute map.
    $attribute_map = simple_ldap_user_variable_get('simple_ldap_user_attribute_map');

    // Create a set of LDAP entries to use during testing.
    for ($i = 0; $i < 5; $i++) {

      // Create a new LDAP User object, and set the attributes.
      $name = $this
        ->randomName();
      $this->ldapUser[$i] = new SimpleLdapUser($name);
      $this->ldapUser[$i]->{$attribute_mail} = $this
        ->randomName() . '@example.com';
      foreach ($attribute_map as $attribute) {
        $attributetype = $server->schema
          ->get('attributetypes', $attribute['ldap']);

        // A syntax type of 1.3.6.1.4.1.1466.115.121.1.27 is an integer.
        if (isset($attributetype['syntax']) && $attributetype['syntax'] == '1.3.6.1.4.1.1466.115.121.1.27') {
          $this->ldapUser[$i]->{$attribute['ldap']} = 1000 + $i;
        }
        else {
          $this->ldapUser[$i]->{$attribute['ldap']} = $this
            ->randomName();
        }
      }

      // Set the DN.
      if (empty($attribute_rdn)) {
        $this->ldapUser[$i]->dn = $attribute_name . '=' . $name . ',' . $basedn;
      }
      else {
        $this->ldapUser[$i]->dn = $attribute_rdn . '=' . $this->ldapUser[$i]->{$attribute_rdn}[0] . ',' . $basedn;
      }

      // Set the user's password.
      $this->userPassword[$i] = $this
        ->randomName();
      SimpleLdapUser::hash($this->userPassword[$i], $this->userPassword[$i]);
      $this->ldapUser[$i]->{$attribute_pass} = $this->userPassword[$i];

      // Save the entry to LDAP.
      $this->ldapUser[$i]
        ->save();

      // If no exception is thrown by save() then the save was successful, but
      // show the DN to make the tester feel better.
      $this
        ->assertTrue($this->ldapUser[$i]->exists, t(':dn was added to LDAP', array(
        ':dn' => $this->ldapUser[$i]->dn,
      )));

      // Verify that the LDAP user can bind.
      $result = $server
        ->bind($this->ldapUser[$i]->dn, $this->userPassword[$i]);
      $this
        ->assertTrue($result, t('Successful bind with :dn using password :pw', array(
        ':dn' => $this->ldapUser[$i]->dn,
        ':pw' => $this->userPassword[$i],
      )));
    }
  }

  /**
   * Inherited parent::tearDown().
   */
  protected function tearDown() {

    // Get module configuration.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Clean up variables written to the database in setUp().
    variable_del('simple_ldap_user_attribute_map');

    // Clean up the LDAP entries that were added for testing.
    foreach ($this->ldapUser as $lu) {

      // Create a new SimpleLdapUser object, which performs a new search based
      // on the name attribute. This accounts for the possibility that the LDAP
      // entry has changed since it was created.
      $ldap_user = new SimpleLdapUser($lu->{$attribute_name}[0]);
      $ldap_user
        ->delete();
      $this
        ->assertFalse($ldap_user->exists, t(':dn was removed from LDAP', array(
        ':dn' => $ldap_user->dn,
      )));
    }
    parent::tearDown();
  }

  /**
   * Verify that a user is unable to log in.
   */
  public function drupalNoLogin(stdClass $user) {
    if ($this->loggedInUser) {
      $this
        ->drupalLogout();
    }
    $edit = array(
      'name' => $user->name,
      'pass' => $user->pass_raw,
    );
    $this
      ->drupalPost('user', $edit, t('Log in'));

    // Verify that the user was unable to log in.
    $pass = $this
      ->assertNoLink(t('Log out'), 0, t('User %name unable to log in.', array(
      '%name' => $user->name,
    )), t('User login'));
    if (!$pass) {
      $this->loggedInUser = $user;
    }
  }

  /**
   * Log in with User 1.
   */
  public function drupalUser1Login() {
    if ($this->loggedInUser) {
      $this
        ->drupalLogout();
    }

    // Load password hashing API.
    if (!function_exists('user_hash_password')) {
      require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
    }

    // Set user1's password to something random in the database.
    $pass = hash('sha256', microtime());
    db_query("UPDATE {users} SET pass = :hash WHERE uid = 1", array(
      ':hash' => user_hash_password($pass),
    ));

    // Log in as user1.
    $admin_user = user_load(1);
    $admin_user->pass_raw = $pass;
    $this
      ->drupalLogin($admin_user);
  }

  /**
   * Verifies that Drupal, LDAP, and the test user values match.
   */
  public function verifySync($suffix = '', $name = NULL, $multi = FALSE) {

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');
    $attribute_mail = simple_ldap_user_variable_get('simple_ldap_user_attribute_mail');
    $server = SimpleLdapServer::singleton();

    // Load the LDAP user.
    if ($name === NULL) {
      $ldap_user = new SimpleLdapUser($this->ldapUser[0]->{$attribute_name}[0]);
      $control = $this->ldapUser[0];
    }
    else {
      $ldap_user = new SimpleLdapUser($name);
      $control = $ldap_user;
    }

    // Load the Drupal user.
    $drupal_user = user_load_multiple(array(), array(
      'name' => $ldap_user->{$attribute_name}[0],
    ), TRUE);
    $drupal_user = reset($drupal_user);

    // Check the mapped fields.
    $attribute_map = simple_ldap_user_variable_get('simple_ldap_user_attribute_map');
    array_unshift($attribute_map, array(
      'drupal' => array(
        'mail',
      ),
      'ldap' => $attribute_mail,
    ));
    foreach ($attribute_map as $attribute) {

      // Skip drupal-to-ldap, one-to-many maps, unless explicitely requested.
      if (count($attribute['drupal']) == 1 || $multi) {

        // Parse the drupal attribute name.
        $drupal = '';
        foreach ($attribute['drupal'] as $drupal_attribute) {
          $type = substr($drupal_attribute, 0, 1);
          switch ($type) {
            case '#':
              $drupal_attribute = substr($drupal_attribute, 1);
              $items = field_get_items('user', $drupal_user, $drupal_attribute);
              $drupal .= ' ' . $items[0]['value'];
              break;
            default:
              $drupal .= ' ' . $drupal_user->{$drupal_attribute};
          }
        }
        $drupal = trim($drupal);

        // Make sure drupal and ldap match.
        $this
          ->assertEqual($ldap_user->{$attribute['ldap']}[0], $drupal, t('The @ldap LDAP attribute :ldap and the @drupal Drupal field :drupal are synchronized.', array(
          '@ldap' => $attribute['ldap'],
          '@drupal' => $drupal_attribute,
          ':ldap' => $ldap_user->{$attribute['ldap']}[0],
          ':drupal' => $drupal,
        )));

        // Only single-valued fields will have a control to check.
        if (count($attribute['drupal']) == 1) {

          // Make sure simple entries match the control.
          $attributetype = $server->schema
            ->get('attributetypes', $attribute['ldap']);

          // A syntax type of 1.3.6.1.4.1.1466.115.121.1.27 is an integer.
          if (isset($attributetype['syntax']) && $attributetype['syntax'] == '1.3.6.1.4.1.1466.115.121.1.27') {
            if ($suffix) {
              $value = hexdec(substr(sha1($suffix), 0, 2));
            }
            else {
              $value = $control->{$attribute['ldap']}[0];
            }
          }
          else {
            $value = $control->{$attribute['ldap']}[0] . $suffix;
          }
          $this
            ->assertEqual($value, $drupal, t(':value matches the control value :control', array(
            ':value' => $drupal,
            ':control' => $value,
          )));
        }
      }
    }
  }

}
class SimpleLdapUserAuthenticationWebTestCase extends SimpleLdapUserTestCase {

  /**
   * Inherited parent::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'Authentication',
      'description' => 'Tests that an LDAP user can authenticate to Drupal with the correct LDAP credentials.',
      'group' => 'Simple LDAP User',
    );
  }

  /**
   * Test user authentication.
   */
  public function testGoodAuthentication() {

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Initialize a user account object.
    $account = new stdClass();
    $account->name = $this->ldapUser[0]->{$attribute_name}[0];
    $account->pass_raw = $this->userPassword[0];

    // Verify that the test user does not exist in Drupal.
    $drupal_user = user_load_by_name($this->ldapUser[0]->{$attribute_name}[0]);
    $this
      ->assertIdentical($drupal_user, FALSE, t('The test user does not exist in Drupal.'));

    // Verify that the user can log in.
    $this
      ->drupalLogin($account);

    // Verify that the Drupal user was created during authentication.
    $drupal_user = user_load_by_name($this->ldapUser[0]->{$attribute_name}[0]);
    $this
      ->assertNotIdentical($drupal_user, FALSE, t('The test user was created in Drupal.'));

    // Verify again that the user can log in, now that the account exists in
    // both Drupal and LDAP.
    $this
      ->drupalLogin($account);

    // Create a new Drupal user that is not in LDAP.
    $account = $this->drupalUser[0];

    // Verify that the user does not exist in LDAP by random chance.
    $ldap_user = new SimpleLdapUser($account->name);
    $this
      ->assertFalse($ldap_user->exists, t('The user account does not exist in LDAP.'));

    // Verify that the user cannot log in.
    $this
      ->drupalNoLogin($account);
  }

  /**
   * Tests invalid login credentials.
   */
  public function testBadAuthentication() {

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Initialize a user account object, with an invalid password.
    $account = new stdClass();
    $account->name = $this->ldapUser[0]->{$attribute_name}[0];
    $account->pass_raw = $this->userPassword[0] . 'invalid';

    // Verify that the test user exists in LDAP.
    $ldap_user = new SimpleLdapUser($account->name);
    $this
      ->assertTrue($ldap_user->exists, t(':name exists in LDAP.', array(
      ':name' => $account->name,
    )));

    // Verify that the test user does not exist in Drupal.
    $drupal_user = user_load_by_name($this->ldapUser[0]->{$attribute_name}[0]);
    $this
      ->assertIdentical($drupal_user, FALSE, t('The test user does not exist in Drupal.'));

    // Verify that the user cannot log in.
    $this
      ->drupalNoLogin($account);

    // Verify that the Drupal user was created during the authentication
    // attempt.
    $drupal_user = user_load_by_name($this->ldapUser[0]->{$attribute_name}[0]);
    $this
      ->assertNotIdentical($drupal_user, FALSE, t('The test user was created in Drupal.'));

    // Verify again that the user cannot log in, now that the account exists in
    // both Drupal and LDAP.
    $this
      ->drupalNoLogin($account);

    // Create a new Drupal user that is not in LDAP.
    $account = $this->drupalUser[0];
    $account->pass_raw = $account->pass_raw . 'invalid';

    // Verify that the user does not exist in LDAP (by random chance).
    $ldap_user = new SimpleLdapUser($account->name);
    $this
      ->assertFalse($ldap_user->exists, t('The user account does not exist in LDAP.'));

    // Verify that the user cannot log in.
    $this
      ->drupalNoLogin($account);

    // Initialize a random user object.
    $account = new stdClass();
    $account->name = $this
      ->randomName();
    $account->pass_raw = $this
      ->randomName();

    // Verify that the user does not exist in LDAP (by random chance).
    $ldap_user = new SimpleLdapUser($account->name);
    $this
      ->assertFalse($ldap_user->exists, t('The user account does not exist in LDAP.'));

    // Verify that the user does not exist in Drupal (by random chance).
    $drupal_user = user_load_by_name($account->name);
    $this
      ->assertIdentical($drupal_user, FALSE, t('The user does not exist in Drupal.'));

    // Attempt to log in.
    $this
      ->drupalNoLogin($account);

    // Verify that the user was not created in LDAP.
    $ldap_user = new SimpleLdapUser($account->name);
    $this
      ->assertFalse($ldap_user->exists, t('The user account does not exist in LDAP.'));

    // Verify that the user was not created in Drupal.
    $drupal_user = user_load_by_name($account->name);
    $this
      ->assertIdentical($drupal_user, FALSE, t('The user does not exist in Drupal.'));
  }

}
class SimpleLdapUserUserOneLoginWebTestCase extends SimpleLdapUserTestCase {

  /**
   * Inherited parent::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'User 1 login',
      'description' => 'Tests whether User 1 can log in, skipping LDAP authentication.',
      'group' => 'Simple LDAP User',
    );
  }

  /**
   * Test User 1 authentication.
   */
  public function testUserOneLogin() {

    // Load user-1.
    $admin_user = user_load(1);

    // Verify that user-1 does not exist in LDAP.
    $ldap_user = new SimpleLdapUser($admin_user->name);
    $this
      ->assertFalse($ldap_user->exists, t('User 1 does not exist in LDAP.'));

    // Attempt to log in.
    $this
      ->drupalUser1Login();

    // Verify that user-1 still does not exist in LDAP.
    $ldap_user = new SimpleLdapUser($admin_user->name);
    $this
      ->assertFalse($ldap_user->exists, t('User 1 does not exist in LDAP.'));
  }

}
class SimpleLdapUserModifyProfileWebTestCase extends SimpleLdapUserTestCase {

  /**
   * Inherited parent::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'User can modify profile',
      'description' => 'Tests whether a user can modify their profile, and that the changes are synchronized to LDAP.',
      'group' => 'Simple LDAP User',
    );
  }

  /**
   * Submits the user profile edit form.
   *
   * Values are taken from the configured test user, and appended by $suffix.
   */
  public function postProfileForm($suffix = '') {

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');
    $attribute_mail = simple_ldap_user_variable_get('simple_ldap_user_attribute_mail');
    $attribute_map = simple_ldap_user_variable_get('simple_ldap_user_attribute_map');
    $server = SimpleLdapServer::singleton();

    // Get the drupal user.
    $drupal_user = user_load_by_name($this->ldapUser[0]->{$attribute_name}[0]);

    // Create the form variable array.
    $edit = array();
    $edit['current_pass'] = $this->userPassword[0];
    $edit['mail'] = $this->ldapUser[0]->{$attribute_mail}[0] . $suffix;
    foreach ($attribute_map as $attribute) {

      // Skip drupal-to-ldap many-to-one mappings.
      if (count($attribute['drupal']) > 1) {
        continue;
      }

      // Get the field name and type.
      $drupal_attribute = reset($attribute['drupal']);
      $type = substr($drupal_attribute, 0, 1);
      $attributetype = $server->schema
        ->get('attributetypes', $attribute['ldap']);

      // A syntax type of 1.3.6.1.4.1.1466.115.121.1.27 is an integer.
      if (isset($attributetype['syntax']) && $attributetype['syntax'] == '1.3.6.1.4.1.1466.115.121.1.27') {
        if ($suffix) {
          $value = hexdec(substr(sha1($suffix), 0, 2));
        }
        else {
          $value = $this->ldapUser[0]->{$attribute['ldap']}[0];
        }
      }
      else {
        $value = $this->ldapUser[0]->{$attribute['ldap']}[0] . $suffix;
      }
      switch ($type) {
        case '#':
          $drupal_attribute = substr($drupal_attribute, 1);
          $edit[$drupal_attribute . '[und][0][value]'] = $value;
          break;
        default:
          $edit[$drupal_attribute] = $value;
      }
    }

    // Submit user edit form.
    $this
      ->drupalPost('user/' . $drupal_user->uid . '/edit', $edit, t('Save'));
  }

  /**
   * User edits profile information.
   */
  public function testUserChangesProfile() {

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Generate a random suffix for testing.
    $suffix = $this
      ->randomName();

    // Initialize a user account object.
    $account = new stdClass();
    $account->name = $this->ldapUser[0]->{$attribute_name}[0];
    $account->pass_raw = $this->userPassword[0];

    // Log in user. This should create/sync an LDAP user (tested elsewhere).
    $this
      ->drupalLogin($account);

    // Submit the profile edit form, and verify synchronization.
    $this
      ->postProfileForm($suffix);
    $this
      ->verifySync($suffix);

    // Reset the values, and verify again.
    $this
      ->postProfileForm();
    $this
      ->verifySync('', NULL, TRUE);
  }

}
class SimpleLdapUserRegistrationTestCase extends SimpleLdapUserTestCase {

  /**
   * Inherited parent::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'User registration',
      'description' => 'Test registration of user under different configurations.',
      'group' => 'Simple LDAP User',
    );
  }

  /**
   * Generate random data for user registration form.
   */
  public function formData(&$name, &$mail) {

    // Generate form data.
    $edit['name'] = $name = $this
      ->randomName();
    $edit['mail'] = $mail = $edit['name'] . '@example.com';

    // Fill in required fields from the user attribute map.
    $server = SimpleLdapServer::singleton();
    $objectclass = simple_ldap_user_variable_get('simple_ldap_user_objectclass');
    $must = array();
    foreach ($objectclass as $o) {
      foreach ($server->schema
        ->must($o, TRUE) as $m) {
        if (!in_array($m, $must)) {
          $must[] = strtolower($m);
        }
      }
    }
    $attribute_map = simple_ldap_user_variable_get('simple_ldap_user_attribute_map');
    foreach ($attribute_map as $attribute) {
      if (in_array($attribute['ldap'], $must)) {
        if (count($attribute['drupal']) > 1) {
          continue;
        }
        $drupal_attribute = reset($attribute['drupal']);
        if (substr($drupal_attribute, 0, 1) == '#') {
          $drupal_attribute = substr($drupal_attribute, 1);
        }
        $attributetype = $server->schema
          ->get('attributetypes', $attribute['ldap']);

        // A syntax type of 1.3.6.1.4.1.1466.115.121.1.27 is an integer.
        if (isset($attributetype['syntax']) && $attributetype['syntax'] == '1.3.6.1.4.1.1466.115.121.1.27') {
          $edit[$drupal_attribute . '[und][0][value]'] = rand(1000, 65535);
        }
        else {
          $edit[$drupal_attribute . '[und][0][value]'] = $this
            ->randomName();
        }
      }
    }
    return $edit;
  }

  /**
   * Tests user registration with email verification.
   */
  public function testRegistrationWithEmailVerification() {

    // Require e-mail verification.
    variable_set('user_email_verification', TRUE);

    // Set registration to administrator only.
    variable_set('user_register', USER_REGISTER_ADMINISTRATORS_ONLY);
    $this
      ->drupalGet('user/register');
    $this
      ->assertResponse(403, t('Registration page is inaccessible when only administrators can create accounts.'));

    // Allow registration by site visitors without administrator approvial.
    variable_set('user_register', USER_REGISTER_VISITORS);
    $edit = $this
      ->formData($name, $mail);
    $this
      ->drupalPost('user/register', $edit, t('Create new account'));
    $this
      ->assertText(t('A welcome message with further instructions has been sent to your e-mail address.'), t('User registered successfully.'));
    $accounts = user_load_multiple(array(), array(
      'name' => $name,
      'mail' => $mail,
    ));
    $new_user = reset($accounts);
    $this
      ->assertTrue($new_user->status, t('New account is active after registration.'));
    $ldap_user = new SimpleLdapUser($name);
    $this
      ->assertTrue($ldap_user->exists, t('New account was provisioned to LDAP.'));

    // Cleanup.
    $ldap_user
      ->delete();

    // Allow registration by site visitors, but require administrator approval.
    variable_set('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL);
    $edit = $this
      ->formData($name, $mail);
    $this
      ->drupalPost('user/register', $edit, t('Create new account'));
    $accounts = user_load_multiple(array(), array(
      'name' => $name,
      'mail' => $mail,
    ));
    $new_user = reset($accounts);
    $this
      ->assertFalse($new_user->status, t('New account is blocked until approved by an administrator.'));
    $ldap_user = new SimpleLdapUser($name);
    $this
      ->assertTrue($ldap_user->exists, t('New account was provisioned to LDAP.'));

    // Cleanup.
    $ldap_user
      ->delete();
  }

  /**
   * Tests user registration without requiring email verification.
   */
  public function testRegistrationWithoutEmailVerification() {

    // Don't require e-mail verification.
    variable_set('user_email_verification', FALSE);

    // Allow registration by site visitors without administrator approval.
    variable_set('user_register', USER_REGISTER_VISITORS);
    $edit = $this
      ->formData($name, $mail);

    // Try entering a mismatching password.
    $edit['pass[pass1]'] = '99999.0';
    $edit['pass[pass2]'] = '99999';
    $this
      ->drupalPost('user/register', $edit, t('Create new account'));
    $this
      ->assertText(t('The specified passwords do not match.'), t('Typing mismatched passwords displays an error message.'));

    // Enter a correct password.
    $edit['pass[pass1]'] = $new_pass = $this
      ->randomName();
    $edit['pass[pass2]'] = $new_pass;
    $this
      ->drupalPost('user/register', $edit, t('Create new account'));
    $accounts = user_load_multiple(array(), array(
      'name' => $name,
      'mail' => $mail,
    ));
    $new_user = reset($accounts);
    $this
      ->assertText(t('Registration successful. You are now logged in.'), t('Users are logged in after registering.'));
    $this
      ->drupalLogout();
    $ldap_user = new SimpleLdapUser($name);
    $this
      ->assertTrue($ldap_user->exists, t('New account has been provisioned to LDAP.'));

    // Cleanup.
    $ldap_user
      ->delete();

    // Allow registration by site visitors, but require administrator approval.
    variable_set('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL);
    $edit = $this
      ->formData($name, $mail);
    $edit['pass[pass1]'] = $pass = $this
      ->randomName();
    $edit['pass[pass2]'] = $pass;
    $this
      ->drupalPost('user/register', $edit, t('Create new account'));
    $this
      ->assertText(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.'), t('Users are notified of pending approval'));
    $ldap_user = new SimpleLdapUser($name);
    $this
      ->assertTrue($ldap_user->exists, t('New account has been provisioned to LDAP.'));

    // Try to login before administrator approval.
    $auth = array(
      'name' => $name,
      'pass' => $pass,
    );
    $this
      ->drupalPost('user/login', $auth, t('Log in'));
    $this
      ->assertText(t('The username @name has not been activated or is blocked.', array(
      '@name' => $name,
    )), t('User cannot login yet.'));

    // Activate the new account.
    $accounts = user_load_multiple(array(), array(
      'name' => $name,
      'mail' => $mail,
    ));
    $new_user = reset($accounts);
    $this
      ->drupalUser1Login();
    $edit = array(
      'status' => 1,
    );
    $this
      ->drupalPost('user/' . $new_user->uid . '/edit', $edit, t('Save'));
    $this
      ->drupalLogout();

    // Login after administrator approval.
    $this
      ->drupalPost('user/login', $auth, t('Log in'));
    $this
      ->assertText(t('Member for'), t('The user can log in after administrator approval.'));

    // Cleanup.
    $ldap_user
      ->delete();
  }

  /**
   * Tests that the values used to register are properly saved.
   */
  public function testRegistrationValues() {

    // Get simple_ldap_user config.
    $objectclass = simple_ldap_user_variable_get('simple_ldap_user_objectclass');
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');
    $attribute_mail = simple_ldap_user_variable_get('simple_ldap_user_attribute_mail');
    $attribute_map = simple_ldap_user_variable_get('simple_ldap_user_attribute_map');

    // Get a list of required LDAP attributes for the user objectclass.
    $server = SimpleLdapServer::singleton();
    $must = array();
    foreach ($objectclass as $o) {
      foreach ($server->schema
        ->must($o, TRUE) as $m) {
        if (!in_array($m, $must)) {
          $must[] = strtolower($m);
        }
      }
    }

    // Allow registration by site visitors without administrator approval.
    variable_set('user_register', USER_REGISTER_VISITORS);

    // Don't require e-mail verification.
    variable_set('user_email_verification', FALSE);

    // Set the default timezone to Brussels.
    variable_set('configurable_timezones', 1);
    variable_set('date_default_timezone', 'Europe/Brussels');

    // Verify that the required mapped fields show up on the registration form.
    $this
      ->drupalGet('user/register');
    foreach ($attribute_map as $field) {
      if (count($field['drupal']) > 1) {
        continue;
      }
      $drupal_attribute = reset($field['drupal']);
      $type = substr($drupal_attribute, 0, 1);
      if (in_array($field['ldap'], $must) && $type == '#') {
        $drupal_attribute = substr($drupal_attribute, 1);
        $this
          ->assertText($drupal_attribute, t(':field appears on the user registration form', array(
          ':field' => $drupal_attribute,
        )));
      }
    }

    // Submit registration form.
    $edit = $this
      ->formData($name, $mail);
    $edit['pass[pass1]'] = $new_pass = $this
      ->randomName();
    $edit['pass[pass2]'] = $new_pass;
    $this
      ->drupalPost(NULL, $edit, t('Create new account'));

    // Load the Drupal user.
    $accounts = user_load_multiple(array(), array(
      'name' => $name,
      'mail' => $mail,
    ));
    $new_user = reset($accounts);

    // Load the LDAP user.
    $ldap_user = new SimpleLdapUser($name);

    // Check the LDAP objectclass(es).
    foreach ($ldap_user->objectclass as $o) {
      $this
        ->assertTrue(in_array($o, $objectclass), t('The LDAP entry has the :o objectclass', array(
        ':o' => $o,
      )));
    }

    // Check user fields.
    $this
      ->assertEqual($new_user->name, $name, t('Drupal username matches.'));
    $this
      ->assertEqual($ldap_user->{$attribute_name}[0], $name, t('LDAP username matches.'));
    $this
      ->assertEqual($new_user->mail, $mail, t('Drupal e-mail address matches.'));
    $this
      ->assertEqual($ldap_user->{$attribute_mail}[0], $mail, t('LDAP e-mail address matches.'));
    foreach ($attribute_map as $field) {
      if (count($field['drupal']) > 1) {
        continue;
      }
      $drupal_attribute = reset($field['drupal']);
      $type = substr($drupal_attribute, 0, 1);
      if (in_array($field['ldap'], $must) && $type == '#') {
        $drupal_attribute = substr($drupal_attribute, 1);
        $this
          ->assertEqual($new_user->{$drupal_attribute}[LANGUAGE_NONE][0]['value'], $edit[$drupal_attribute . '[und][0][value]'], t('The :field Drupal field value was correctly saved.', array(
          ':field' => $drupal_attribute,
        )));
        $this
          ->assertEqual($ldap_user->{$field['ldap']}[0], $edit[$drupal_attribute . '[und][0][value]'], t('The :field LDAP attribute was correctly saved.', array(
          ':field' => $field['ldap'],
        )));
      }
    }

    // Cleanup.
    $ldap_user
      ->delete();
  }

}
class SimpleLdapUserSyncTestCase extends SimpleLdapUserTestCase {

  /**
   * Inherited parent::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'User data synchronization',
      'description' => 'Test data synchronization between LDAP and Drupal.',
      'group' => 'Simple LDAP User',
    );
  }

  /**
   * Modifies the test user account in LDAP.
   */
  public function modifyLdap($suffix = '') {

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');
    $attribute_mail = simple_ldap_user_variable_get('simple_ldap_user_attribute_mail');

    // Load the LDAP Server.
    $server = SimpleLdapServer::singleton();

    // Search for the User account.
    $ldap_user = new SimpleLdapUser($this->ldapUser[0]->{$attribute_name}[0]);

    // Modify the mapped attributes.
    $attribute_map = simple_ldap_user_variable_get('simple_ldap_user_attribute_map');
    array_unshift($attribute_map, array(
      'drupal' => array(
        'mail',
      ),
      'ldap' => $attribute_mail,
    ));
    foreach ($attribute_map as $attribute) {
      if (count($attribute['drupal']) == 1) {
        $attributetype = $server->schema
          ->get('attributetypes', $attribute['ldap']);

        // A syntax type of 1.3.6.1.4.1.1466.115.121.1.27 is an integer.
        if (isset($attributetype['syntax']) && $attributetype['syntax'] == '1.3.6.1.4.1.1466.115.121.1.27') {
          if ($suffix) {
            $value = hexdec(substr(sha1($suffix), 0, 2));
          }
          else {
            $value = $this->ldapUser[0]->{$attribute['ldap']}[0];
          }
        }
        else {
          $value = $this->ldapUser[0]->{$attribute['ldap']}[0] . $suffix;
        }
        try {
          $server
            ->modify($ldap_user->dn, array(
            $attribute['ldap'] => $value,
          ), 'replace');
          $entry = $server
            ->entry($ldap_user->dn);
          $this
            ->assertEqual($value, $entry[0][$attribute['ldap']][0], t('Modified @attr LDAP attribute to :value.', array(
            '@attr' => $attribute['ldap'],
            ':value' => $value,
          )));
        } catch (SimpleLdapException $e) {
          $this
            ->error($e
            ->getMessage());
        }
      }
    }
  }

  /**
   * Tests data synchronization using hook_user_login().
   */
  public function testSyncOnHookUserLogin() {

    // Set the sync trigger to hook_user_login
    variable_set('simple_ldap_user_sync', 'hook_user_login');

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Initialize a user account object.
    $account = new stdClass();
    $account->name = $this->ldapUser[0]->{$attribute_name}[0];
    $account->pass_raw = $this->userPassword[0];

    // Log in with the test user, this should do the initial account sync
    // (tested elsewhere).
    $this
      ->drupalLogin($account);

    // Generate a random value to append.
    $suffix = $this
      ->randomName();

    // Drupal is the authoritative source, Change all of the mapped fields,
    // login, and verify synchronization.
    variable_set('simple_ldap_user_source', 'drupal');
    $this
      ->modifyLdap($suffix);
    $this
      ->drupalLogin($account);
    $this
      ->verifySync();

    // LDAP is the authoritative source. Change all of the mapped fields, login,
    // and verify synchronization.
    variable_set('simple_ldap_user_source', 'ldap');
    $this
      ->modifyLdap($suffix);
    $this
      ->drupalLogin($account);
    $this
      ->verifySync($suffix);

    // Clean up by removing the suffix from the LDAP entry, and resyncing.
    $this
      ->modifyLdap();
    $this
      ->drupalLogin($account);
    $this
      ->verifySync();
  }

  /**
   * Tests synchronization using hook_user_load().
   */
  public function testSyncOnHookUserLoad() {

    // Set the sync trigger to hook_user_load
    variable_set('simple_ldap_user_sync', 'hook_user_load');

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Initialize a user account object.
    $account = new stdClass();
    $account->name = $this->ldapUser[0]->{$attribute_name}[0];
    $account->pass_raw = $this->userPassword[0];

    // Log in with the test user, this should do the initial account sync
    // (tested elsewhere).
    $this
      ->drupalLogin($account);

    // Generate a random value to append.
    $suffix = $this
      ->randomName();

    // Drupal is the authoritative source. Change all of the mapped fields, load
    // the user, and verify synchronization.
    variable_set('simple_ldap_user_source', 'drupal');
    $this
      ->modifyLdap();
    $drupal_user = user_load_multiple(array(), array(
      'name' => $this->ldapUser[0]->{$attribute_name}[0],
    ), TRUE);
    $this
      ->verifySync();

    // LDAP is the authoritative source. Change all of the mapped fields, load
    // the user, and verify synchronization.
    variable_set('simple_ldap_user_source', 'ldap');
    $this
      ->modifyLdap($suffix);
    $drupal_user = user_load_multiple(array(), array(
      'name' => $this->ldapUser[0]->{$attribute_name}[0],
    ), TRUE);
    $this
      ->verifySync($suffix);

    // Clean up by removing the suffix from the LDAP entry, and resyncing.
    $this
      ->modifyLdap();
    $drupal_user = user_load_multiple(array(), array(
      'name' => $this->ldapUser[0]->{$attribute_name}[0],
    ), TRUE);
    $this
      ->verifySync();
  }

}
class SimpleLdapUserPasswordResetTestCase extends SimpleLdapUserTestCase {

  /**
   * Inherited parent::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'User password change',
      'description' => 'Ensure that a user can change their password and that it is updated in LDAP.',
      'group' => 'Simple LDAP User',
    );
  }

  /**
   * Tests that a user can change thier password.
   */
  public function testPasswordChange() {

    // Load configuration variables.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Initialize a user account object.
    $account = new stdClass();
    $account->name = $this->ldapUser[0]->{$attribute_name}[0];
    $account->pass_raw = $this->userPassword[0];

    // Log in user. This should create/sync an LDAP user (tested elsewhere).
    $this
      ->drupalLogin($account);

    // Get the drupal user.
    $drupal_user = user_load_by_name($this->ldapUser[0]->{$attribute_name}[0]);

    // Create the form variable array.
    $edit = array();
    $edit['current_pass'] = $this->userPassword[0];
    $edit['pass[pass1]'] = $this
      ->randomName();
    $edit['pass[pass2]'] = $edit['pass[pass1]'];

    // Submit user edit form.
    $this
      ->drupalPost('user/' . $drupal_user->uid . '/edit', $edit, 'Save');

    // Verify that the old password no longer works.
    $this
      ->drupalNoLogin($account);

    // Verify that the new password works.
    $account->pass_raw = $edit['pass[pass1]'];
    $this
      ->drupalLogin($account);

    // Reset the password.
    $edit['current_pass'] = $edit['pass[pass1]'];
    $edit['pass[pass1]'] = $this->userPassword[0];
    $edit['pass[pass2]'] = $edit['pass[pass1]'];

    // Submit user edit form.
    $this
      ->drupalPost('user/' . $drupal_user->uid . '/edit', $edit, 'Save');

    // Verify that it was changed back.
    $account->pass_raw = $edit['pass[pass1]'];
    $this
      ->drupalLogin($account);
  }

  /**
   * Tests password reset before a Drupal user is created.
   */
  public function testLdapNoDrupalPasswordReset() {

    // Get the configuration.
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Verify that the test user does not exist in Drupal.
    $drupal_user = user_load_by_name($this->ldapUser[0]->{$attribute_name}[0]);
    $this
      ->assertIdentical($drupal_user, FALSE, t('The test user does not exist in Drupal.'));

    // Submit the password reset form.
    $edit = array(
      'name' => $this->ldapUser[0]->{$attribute_name}[0],
    );
    $this
      ->drupalPost('user/password', $edit, t('E-mail new password'));
    $this
      ->assertText(t('Further instructions have been sent to your e-mail address.'), t('A new password was successfully requested.'));

    // Verify that the Drupal user was created.
    $drupal_user = user_load_by_name($this->ldapUser[0]->{$attribute_name}[0]);
    $this
      ->assertNotIdentical($drupal_user, FALSE, t('The test user was created in Drupal.'));
  }

}
class SimpleLdapUserDeleteUserTestCase extends SimpleLdapUserTestCase {

  /**
   * Inherited parent::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'Delete user',
      'description' => 'Tests that deleting a user in Drupal also deletes the user from LDAP.',
      'group' => 'Simple LDAP User',
    );
  }

  /**
   * Tests user deletion.
   */
  public function testDeleteUser() {

    // Disable email verification and admin approval.
    variable_set('user_email_verification', FALSE);
    variable_set('user_register', USER_REGISTER_VISITORS);

    // Make sure the system is set to delete from LDAP
    variable_set('simple_ldap_user_delete_from_ldap', 1);

    // Generate user registration formdata.
    $edit['name'] = $name = $this
      ->randomName();
    $edit['mail'] = $mail = $name . '@example.com';
    $edit['pass[pass1]'] = $pass = $this
      ->randomName();
    $edit['pass[pass2]'] = $pass;

    // Fill in required fields from the user attribute map.
    $server = SimpleLdapServer::singleton();
    $objectclass = simple_ldap_user_variable_get('simple_ldap_user_objectclass');
    $must = array();
    foreach ($objectclass as $o) {
      foreach ($server->schema
        ->must($o, TRUE) as $m) {
        if (!in_array($m, $must)) {
          $must[] = strtolower($m);
        }
      }
    }
    $attribute_map = simple_ldap_user_variable_get('simple_ldap_user_attribute_map');
    foreach ($attribute_map as $attribute) {
      if (in_array($attribute['ldap'], $must)) {
        if (count($attribute['drupal']) > 1) {
          continue;
        }
        $drupal_attribute = reset($attribute['drupal']);
        if (substr($drupal_attribute, 0, 1) == '#') {
          $drupal_attribute = substr($drupal_attribute, 1);
        }
        $attributetype = $server->schema
          ->get('attributetypes', $attribute['ldap']);

        // A syntax type of 1.3.6.1.4.1.1466.115.121.1.27 is an integer.
        if (isset($attributetype['syntax']) && $attributetype['syntax'] == '1.3.6.1.4.1.1466.115.121.1.27') {
          $edit[$drupal_attribute . '[und][0][value]'] = rand(1000, 65535);
        }
        else {
          $edit[$drupal_attribute . '[und][0][value]'] = $this
            ->randomName();
        }
      }
    }

    // Submit the registration form to create the user.
    $this
      ->drupalPost('user/register', $edit, t('Create new account'));
    $accounts = user_load_multiple(array(), array(
      'name' => $name,
      'mail' => $mail,
    ));
    $drupal_user = reset($accounts);
    $this
      ->assertText(t('Registration successful. You are now logged in.'), t('Users are logged in after registering.'));
    $this
      ->drupalLogout();

    // Verify that the user exists in LDAP.
    $ldap_user = new SimpleLdapUser($name);
    $this
      ->assertTrue($ldap_user->exists, t('The user was created in LDAP.'));

    // Log in as user1.
    $this
      ->drupalUser1Login();

    // Submit the delete-user form.
    $edit = array();
    $edit['user_cancel_method'] = 'user_cancel_delete';
    $this
      ->drupalPost('user/' . $drupal_user->uid . '/cancel', $edit, t('Cancel account'));
    $this
      ->assertText(t('@name has been deleted.', array(
      '@name' => $name,
    )), t('The user was deleted from Drupal.'));

    // Verify that the user was deleted from LDAP.
    $ldap_user = new SimpleLdapUser($name);
    $this
      ->assertFalse($ldap_user->exists, t('The user was deleted from LDAP.'));
  }

}
class SimpleLdapUserMassImportExportTestCase extends SimpleLdapUserTestCase {

  /**
   * Inherited parent::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'Mass Import/Export',
      'description' => 'Tests mass user import from LDAP, and export to LDAP.',
      'group' => 'Simple LDAP User',
    );
  }

  /**
   * Test mass export.
   */
  public function testExport() {

    // Log in as user 1.
    $this
      ->drupalUser1Login();

    // Clear cache, otherwise the export option is not present.
    $this
      ->drupalPost('admin/config/development/performance', array(), t('Clear all caches'));

    // Verify that the drupal users do not exist in LDAP.
    foreach ($this->drupalUser as $drupal_user) {
      $ldap_user = new SimpleLdapUser($drupal_user->name);
      $this
        ->assertFalse($ldap_user->exists, t(':name does not exist in LDAP.', array(
        ':name' => $drupal_user->name,
      )));
    }

    // Submit the export user form.
    $edit = array(
      'operation' => 'simple_ldap_user_export',
    );
    foreach ($this->drupalUser as $drupal_user) {
      $edit['accounts[' . $drupal_user->uid . ']'] = TRUE;
    }
    $this
      ->drupalPost('admin/people', $edit, t('Update'));

    // Verify that the users were exported to LDAP.
    foreach ($this->drupalUser as $drupal_user) {
      $ldap_user = new SimpleLdapUser($drupal_user->name);
      $this
        ->assertTrue($ldap_user->exists, t(':name exists in LDAP at :dn.', array(
        ':name' => $drupal_user->name,
        ':dn' => $ldap_user->dn,
      )));
      $this
        ->verifySync('', $drupal_user->name);

      // Cleanup LDAP.
      $ldap_user
        ->delete();
      $this
        ->assertFalse($ldap_user->exists, t(':dn was removed from LDAP', array(
        ':dn' => $ldap_user->dn,
      )));
    }
  }

  /**
   * Test mass import.
   */
  public function testImport() {

    // Get configuration.
    $server = SimpleLdapServer::singleton();
    $basedn = simple_ldap_user_variable_get('simple_ldap_user_basedn');
    $scope = simple_ldap_user_variable_get('simple_ldap_user_scope');
    $attribute_name = simple_ldap_user_variable_get('simple_ldap_user_attribute_name');

    // Log in as user 1.
    $this
      ->drupalUser1Login();

    // Clear cache, otherwise the import menu item doesn't work.
    $this
      ->drupalPost('admin/config/development/performance', array(), t('Clear all caches'));

    // Verify that the LDAP users do not exist in Drupal.
    foreach ($this->ldapUser as $ldap_user) {
      $drupal_user = user_load_by_name($ldap_user->{$attribute_name}[0]);
      $this
        ->assertIdentical($drupal_user, FALSE, t('The user :name does not exist in Drupal.', array(
        ':name' => $ldap_user->{$attribute_name}[0],
      )));
    }

    // Submit the import user form.
    $edit = array();

    // Perform the same search that is done to generate the form, so all of the
    // extra entries can be set to false. We just want to import the users
    // created specifically for this test.
    $filter = '(&(' . $attribute_name . '=*)' . SimpleLdapUser::filter() . ')';
    $ldap_users = SimpleLdap::clean($server
      ->search($basedn, $filter, $scope, array(
      'dn',
      $attribute_name,
    )));
    foreach ($ldap_users as $ldap_user) {
      $edit['users[' . $ldap_user[$attribute_name][0] . ']'] = FALSE;
    }

    // Select the users that were created for this test.
    foreach ($this->ldapUser as $ldap_user) {
      $edit['users[' . $ldap_user->{$attribute_name}[0] . ']'] = TRUE;
    }
    $this
      ->drupalPost('admin/people/simple_ldap_user_import', $edit, t('Import'));

    // Verify that the users were imported into Drupal.
    foreach ($this->ldapUser as $ldap_user) {
      $drupal_user = user_load_by_name($ldap_user->{$attribute_name}[0]);
      $this
        ->assertNotIdentical($drupal_user, FALSE, t('The test user :name was created in Drupal.', array(
        ':name' => $ldap_user->{$attribute_name}[0],
      )));
      $this
        ->verifySync('', $ldap_user->{$attribute_name}[0]);
    }
  }

}