You are here

contact_attach.test in Contact Attach 7

Tests for the Contact Attach module.

File

contact_attach.test
View source
<?php

/**
 * @file
 * Tests for the Contact Attach module.
 */

/**
 * Tests the Contact Attach settings form.
 */
class ContactAttachSettingsFormTestCase extends DrupalWebTestCase {
  protected $profile = 'testing';
  public static function getInfo() {
    return array(
      'name' => 'Contact Attach settings form',
      'description' => 'Tests the settings form for the Contact Attach module.',
      'group' => 'Contact Attach',
    );
  }
  function setUp() {
    parent::setUp('contact_attach');

    // Create a default role for site administrators.
    $admin_role = new stdClass();
    $admin_role->name = 'administrator';
    $admin_role->weight = 2;
    user_role_save($admin_role);

    // Set this as the administrator role.
    variable_set('user_admin_role', $admin_role->rid);
  }

  /**
   * Tests the module settings form with granted permissions for various roles.
   */
  function testContactAttachSettingsForm() {
    $admin_user = $this
      ->drupalCreateUser(array(
      'administer site configuration',
    ));
    $this
      ->drupalLogin($admin_user);
    $this
      ->drupalGet('admin/config/media/contact_attach');
    $this
      ->assertResponse(200);
    $this
      ->assertUniqueText(t('Settings for the site-wide contact form'));
    $this
      ->assertUniqueText(t('Settings for personal contact forms'));
    $this
      ->assertNoText(t('Use simple file field.'));
    module_enable(array(
      'file',
    ), FALSE);
    $this
      ->drupalGet('admin/config/media/contact_attach');
    $this
      ->assertUniqueText(t('Use simple file field.'));

    // Check that setting the simple field type setting works.
    $this
      ->drupalPost('admin/config/media/contact_attach', array(
      'contact_attach_simple_field' => 1,
    ), t('Save configuration'));
    $this
      ->assertUniqueText(t('The configuration options have been saved.'), 'Settings successfully saved.');
    $this
      ->assertRaw('name="contact_attach_simple_field" value="1" checked="checked"', 'Setting contact_attach_simple_field was fetched properly after being saved.');
    $this
      ->drupalPost('admin/config/media/contact_attach', array(
      'contact_attach_simple_field' => FALSE,
    ), t('Save configuration'));
    $this
      ->assertUniqueText(t('The configuration options have been saved.'), 'Settings successfully saved.');
    $this
      ->assertRaw('name="contact_attach_simple_field" value="1" cl', 'Setting contact_attach_simple_field was fetched properly after being saved.');

    // Check that the administrator role is listed on the settings page even
    // when not having set permissions and test that we can define its settings.
    $this
      ->checkPermittedRoleOnSettingsPage(variable_get('user_admin_role'), FALSE);

    // Check that the anonymous role is listed on the settings page after
    // granting it permissions and test that we can define its settings.
    $anon_role = $this
      ->checkPermittedRoleOnSettingsPage(DRUPAL_ANONYMOUS_RID);

    // Check that the anonymous role is not listed on the settings page after
    // revoking its permissions.
    $this
      ->revokePermsAndCheckIfRoleNotListed($anon_role);
    $admin_user_roles = $admin_user->roles;
    unset($admin_user_roles[DRUPAL_AUTHENTICATED_RID]);
    reset($admin_user_roles);
    $created_role_rid = key($admin_user_roles);

    // Check that the created role is listed on the settings page after granting
    // it permissions and test that we can define its settings.
    $created_role = $this
      ->checkPermittedRoleOnSettingsPage($created_role_rid);

    // Check that the created role is not listed on the settings page after
    // revoking its permissions.
    $this
      ->revokePermsAndCheckIfRoleNotListed($created_role);

    // Check that the authenticated user role is listed on the settings page
    // after granting it permissions and test that we can define its settings.
    $auth_role = $this
      ->checkPermittedRoleOnSettingsPage(DRUPAL_AUTHENTICATED_RID);

    // Check that the role created when the admin user was created is listed on
    // the settings page after granting the authenticated user role permissions
    // and test that we can define its settings.
    $this
      ->checkPermittedRoleOnSettingsPage($created_role->rid, FALSE);

    // Check that the authenticated user role and the created role that inherit
    // the permissions are not listed on the settings page after revoking the
    // permissions of the authenticated user role.
    $this
      ->revokePermsAndCheckIfRoleNotListed($auth_role, array(
      $created_role->name,
    ));
  }

  /**
   * Checks if the role is listed on the settings page when having permissions.
   *
   * Also tests submitting settings for the role.
   *
   * @param int $rid
   *   The role ID of the role to be checked.
   * @param bool $grant_perms
   *   (optional) TRUE if permissions should be granted; FALSE otherwise.
   *
   * @return object
   *   A fully-loaded role object as returned by user_role_load().
   */
  function checkPermittedRoleOnSettingsPage($rid, $grant_perms = TRUE) {
    if ($grant_perms) {
      user_role_grant_permissions($rid, array(
        'attach files on site-wide contact form',
        'attach files on personal contact forms',
      ));
    }
    $this
      ->drupalGet('admin/config/media/contact_attach');
    $role = user_role_load($rid);
    $this
      ->runSettingsFormTestForRole($role);
    return $role;
  }

  /**
   * Revokes permissions and checks if the role is listed on the settings page.
   *
   * @param object $role
   *   A fully-loaded role object as returned by user_role_load().
   * @param array $extra_role_names
   *   (optional) An array of supplementary role names to check for.
   */
  function revokePermsAndCheckIfRoleNotListed($role, $extra_role_names = array()) {
    user_role_revoke_permissions($role->rid, array(
      'attach files on site-wide contact form',
      'attach files on personal contact forms',
    ));
    $this
      ->drupalGet('admin/config/media/contact_attach');
    $this
      ->assertNoText(t('Settings for the @role role', array(
      '@role' => $role->name,
    )));
    foreach ($extra_role_names as $role_name) {
      $this
        ->assertNoText(t('Settings for the @role role', array(
        '@role' => $role_name,
      )));
    }
  }

  /**
   * Posts valid settings for the specified role on the module settings page.
   *
   * @param object $role
   *   A fully-loaded role object as returned by user_role_load().
   */
  function postValidRoleSettings($role) {
    $max_size = format_size(file_upload_max_size());

    // Set valid settings.
    $field_values = array(
      'number_site[' . $role->rid . ']' => 3,
      'extensions_site[' . $role->rid . ']' => 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp patch',
      'uploadsize_site[' . $role->rid . ']' => $max_size - 0.1,
      'number_user[' . $role->rid . ']' => 2,
      'extensions_user[' . $role->rid . ']' => 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp xml',
      'uploadsize_user[' . $role->rid . ']' => $max_size - 0.2,
    );
    $edit = array();
    foreach ($field_values as $field_key => $field_value) {
      $edit['contact_attach_' . $field_key] = $field_value;
    }
    $this
      ->drupalPost('admin/config/media/contact_attach', $edit, t('Save configuration'));
    $this
      ->assertUniqueText(t('The configuration options have been saved.'), 'Settings successfully saved.');
    foreach ($field_values as $field_key => $field_value) {
      $this
        ->assertRaw('name="contact_attach_' . $field_key . '" value="' . $field_value . '"', 'Setting contact_attach_' . $field_key . ' was fetched properly after being saved.');
    }
  }

  /**
   * Posts invalid settings for the specified role on the module settings page.
   *
   * @param object $role
   *   A fully-loaded role object as returned by user_role_load().
   */
  function postInvalidRoleSettings($role) {
    $max_size = format_size(file_upload_max_size());

    // Set invalid settings.
    $edit = array(
      'contact_attach_number_site[' . $role->rid . ']' => 'n',
      'contact_attach_uploadsize_site[' . $role->rid . ']' => 'n',
      'contact_attach_number_user[' . $role->rid . ']' => 0,
      'contact_attach_uploadsize_user[' . $role->rid . ']' => 0,
    );
    $this
      ->drupalPost('admin/config/media/contact_attach', $edit, t('Save configuration'));
    $this
      ->assertNoText(t('The configuration options have been saved.'), 'Settings NOT successfully saved.');
    $this
      ->assertUniqueText(t('The number of file attachments for the @role role must be a positive integer.', array(
      '@role' => $role->name,
    )), 'Setting rightfully failed validation.');
    $this
      ->assertNoUniqueText(t('The @role role file size limit must be a number and greater than zero.', array(
      '@role' => $role->name,
    )), 'Setting rightfully failed validation.');
    $this
      ->assertUniqueText(t('The number of file attachments for the @role role cannot be 0. If you want to disable the ability of attaching files on contact forms for a role, revoke its permission on the permissions page.', array(
      '@role' => $role->name,
    )), 'Setting rightfully failed validation.');
    $edit = array(
      'contact_attach_uploadsize_site[' . $role->rid . ']' => $max_size + 1,
    );
    $this
      ->drupalPost('admin/config/media/contact_attach', $edit, t('Save configuration'));
    $this
      ->assertNoText(t('The configuration options have been saved.'), 'Settings NOT successfully saved.');
    $this
      ->assertRaw(t("Your PHP settings limit the maximum file size per upload to %size.<br/>Depending on your server environment, these settings may be changed in the system-wide php.ini file, a php.ini file in your Drupal root directory, in your Drupal site's settings.php file, or in the .htaccess file in your Drupal root directory.", array(
      '%size' => $max_size,
    )), 'Setting rightfully failed validation.');
  }

  /**
   * Tests the module settings form for the specified role.
   *
   * @param $role
   *   A fully-loaded role object as returned by user_role_load().
   */
  function runSettingsFormTestForRole($role) {
    $this
      ->assertNoUniqueText(t('Settings for the @role role', array(
      '@role' => $role->name,
    )));

    // Post valid values and assert that they are stored.
    $this
      ->postValidRoleSettings($role);

    // Post invalid values and assert that they are caught by the validator.
    $this
      ->postInvalidRoleSettings($role);
  }

}

/**
 * Tests the Contact Attach functionality for site-wide and user contact forms.
 */
class ContactAttachContactFormsTestCase extends DrupalWebTestCase {
  protected $profile = 'testing';
  public static function getInfo() {
    return array(
      'name' => 'Contact Attach contact forms',
      'description' => 'Tests attachment functionality on the site-wide and user contact forms.',
      'group' => 'Contact Attach',
    );
  }
  function setUp() {
    parent::setUp('contact_attach');

    // Grant all users access to contact forms.
    user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array(
      'access site-wide contact form',
      'access user contact forms',
    ));
    user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array(
      'access site-wide contact form',
      'access user contact forms',
    ));

    // Create a default role for site administrators.
    $admin_role = new stdClass();
    $admin_role->name = 'administrator';
    $admin_role->weight = 2;
    user_role_save($admin_role);
    user_role_grant_permissions($admin_role->rid, array_keys(module_invoke_all('permission')));

    // Set this as the administrator role.
    variable_set('user_admin_role', $admin_role->rid);

    // Enable contact forms for users by default.
    variable_set('contact_default_status', TRUE);

    // Avoid that the flood control causes the tests to fail.
    variable_set('contact_threshold_limit', 50);

    // Create an admin user for its contact form to be used in the tests.
    $this->admin_user = $this
      ->drupalCreateUser();

    // Create a user that only has the authenticated user role.
    $this->auth_user = $this
      ->drupalCreateUser();

    // drupalCreateUser() does not remove the anonymous role from the new user.
    unset($this->auth_user->roles[DRUPAL_ANONYMOUS_RID]);

    // Create a user with its own role that will later be assigned a 2nd role.
    $this->specific_role_user = $this
      ->drupalCreateUser(array(
      'access site-wide contact form',
      'access user contact forms',
    ));

    // Figure out rid of the role created when specific_role_user was created.
    $specific_user_roles = $this->specific_role_user->roles;
    unset($specific_user_roles[DRUPAL_AUTHENTICATED_RID]);
    reset($specific_user_roles);
    $this->created_role_rid = key($specific_user_roles);

    // Create a second role for the specific role user.
    $this->created_role_2_rid = $this
      ->drupalCreateRole(array(
      'access site-wide contact form',
      'access user contact forms',
    ));

    // Assign the "administrator" role to the admin user.
    db_insert('users_roles')
      ->fields(array(
      'uid' => $this->admin_user->uid,
      'rid' => $admin_role->rid,
    ))
      ->execute();

    // Assign the specific role user the second created role.
    db_insert('users_roles')
      ->fields(array(
      'uid' => $this->specific_role_user->uid,
      'rid' => $this->created_role_2_rid,
    ))
      ->execute();
    $this->specific_role_user->roles[$this->created_role_2_rid] = (string) $this->created_role_2_rid;
  }

  /**
   * Tests the attachment functionality on the site-wide and user contact forms.
   */
  function testContactAttachContactForms() {
    $this->contact_forms = array(
      'contact' => 'attach files on site-wide contact form',
      'user/' . $this->admin_user->uid . '/contact' => 'attach files on personal contact forms',
    );
    $this->contact_forms_short = array(
      'site' => 'contact',
      'user' => 'user/' . $this->admin_user->uid . '/contact',
    );
    $this->message = array(
      'name' => 'Kalle Klovn',
      'mail' => 'kalle.klovn@example.com',
      'subject' => 'Test message',
      'message' => "This is a test message with 1 attachment.",
    );
    $this->file_field_types = array(
      'simple_file_field',
      'managed_file_field',
    );

    // We need to test everything with and without the file module enabled.
    foreach ($this->file_field_types as $this->file_field_type) {
      if ($this->file_field_type === 'managed_file_field') {
        module_enable(array(
          'file',
        ), FALSE);
      }

      // Check the existence of attachment fields on the site-wide and personal
      // contact forms with and without permissions granted.
      $this
        ->checkExistenceOfAttachmentFields(DRUPAL_ANONYMOUS_RID);
      $this
        ->checkExistenceOfAttachmentFields(DRUPAL_AUTHENTICATED_RID, $this->auth_user);

      // Check to see that the right field type is used for attachments.
      $this
        ->checkAttachmentFieldType();

      // Verify that the user can not send messages with attachments when the user
      // has permission to attach files, but no settings have been set.
      $this
        ->submitAttachmentWhenNoSettingsSet();
      $this
        ->submitAttachmentWhenNoSettingsSet($this->auth_user);

      // Verify that the correct number of attachments appear on the contact forms
      // after this setting has been set.
      $this->attachment_numbers = array();
      $this
        ->checkNumberOfAttachmentFields(DRUPAL_ANONYMOUS_RID, '2');
      $this
        ->checkNumberOfAttachmentFields(DRUPAL_AUTHENTICATED_RID, '5', $this->auth_user);

      // Ensure that the number of attachments for the specific role overrides the
      // number of attachments defined for the authenticated user role.
      $this
        ->checkNumberOfAttachmentFields($this->created_role_rid, '4', $this->specific_role_user);

      // Ensure that the number of attachments for the user's second role is
      // accounted for, but that the number of attachments of the first created
      // role is used, as it's higher.
      $this
        ->checkNumberOfAttachmentFields($this->created_role_2_rid, '3', $this->specific_role_user);

      // Verify that the correct allowed extensions and maximum file size is taken
      // into account after these settings have been set.
      $this->extensions = array();
      $this->uploadsizes = array();
      $this
        ->submitWithAttachments(DRUPAL_ANONYMOUS_RID, 'html', '0.00107421875');
      $this
        ->submitWithAttachments(DRUPAL_AUTHENTICATED_RID, 'sql', '0.00131835938', $this->auth_user);

      // Ensure that the maximum allowed file size for the specific role overrides
      // the maximum allowed file size defined for the authenticated user role.
      $this
        ->submitWithAttachments($this->created_role_rid, 'patch', '0.00126953125', $this->specific_role_user);

      // Ensure that the settings for the user's second role is accounted for, but
      // that the maximum upload size of the first created role is used, as it's
      // higher.
      $this
        ->submitWithAttachments($this->created_role_2_rid, 'tgv', '0.001171875', $this->specific_role_user);

      // Reset all of the module's persistent variables and users' permissions
      // for the next run.
      $this
        ->resetPersistentVariablesAndPermissions();
    }
  }

  /**
   * Checks existence of attachment fields on site-wide and user contact forms.
   *
   * @param int $rid
   *   The role ID of the role to grant permissions.
   * @param object $user
   *   (optional) A fully-loaded $user object of the user to log in. Defaults to
   *   NULL.
   */
  function checkExistenceOfAttachmentFields($rid, $user = NULL) {
    if ($user) {
      $this
        ->drupalLoginWithUserGlobalRolesUpdate($user);
    }
    foreach ($this->contact_forms as $contact_form => $permission) {
      $this
        ->drupalGet($contact_form);

      // Ensure that there are no attachment fields when the user's roles do not
      // have the necessary permissions to attach files.
      $this
        ->assertNoRaw('files[contact_attach_1]', 'Attachment field does NOT appear on contact form.');
      user_role_grant_permissions($rid, array(
        $permission,
      ));
      $this
        ->drupalGet($contact_form);

      // Ensure that there is one attachment field when the user's roles have
      // permission to attach files, but the settings for the roles have not
      // been set.
      $this
        ->assertRaw('files[contact_attach_1]', '1 attachment field appears on contact form.');
      $this
        ->assertNoRaw('files[contact_attach_2]', 'More than 1 attachment field does NOT appear on contact form.');
    }
    if ($user) {
      $this
        ->drupalLogoutWithUserGlobalRolesUpdate();
    }
  }

  /**
   * Checks field type of attachment fields on site-wide and user contact forms.
   */
  function checkAttachmentFieldType() {
    foreach ($this->contact_forms as $contact_form => $permission) {

      // Ensure that the field type is of the right type in accordance with the
      // value of the contact_attach_simple_field persistent variable.
      $this
        ->drupalGet($contact_form);
      if ($this->file_field_type === 'managed_file_field') {
        $this
          ->assertRaw('edit-contact-attach-1-upload', 'The attachment field type is managed_file.');
      }
      else {
        $this
          ->assertNoRaw('edit-contact-attach-1-upload', 'The attachment field type is not managed_file.');
      }
      variable_set('contact_attach_simple_field', 1);
      $this
        ->drupalGet($contact_form);
      $this
        ->assertNoRaw('edit-contact-attach-1-upload', 'The attachment field type is not managed_file.');
      variable_set('contact_attach_simple_field', 0);
      $this
        ->drupalGet($contact_form);
      if ($this->file_field_type === 'managed_file_field') {
        $this
          ->assertRaw('edit-contact-attach-1-upload', 'The attachment field type is managed_file.');
      }
      else {
        $this
          ->assertNoRaw('edit-contact-attach-1-upload', 'The attachment field type is not managed_file.');
      }
    }
  }

  /**
   * Submits contact forms with attachments when no settings are set.
   *
   * @param object $user
   *   (optional) A fully-loaded $user object of the user to log in. Defaults to
   *   NULL.
   */
  function submitAttachmentWhenNoSettingsSet($user = NULL) {
    if ($user) {
      $this
        ->drupalLoginWithUserGlobalRolesUpdate($user);
    }
    foreach ($this->contact_forms as $contact_form => $permission) {

      // Ensure that the user can not send messages with attachments when no
      // settings have been set for the user's roles.
      $file = current($this
        ->drupalGetTestFiles('image', 1831));
      $this->message['files[contact_attach_1]'] = drupal_realpath($file->uri);
      $this
        ->drupalPost($contact_form, $this->message, t('Send message'));
      $this
        ->assertNoText(t('Your message has been sent.'));
      $this
        ->assertUniqueText(t('The specified file @filename could not be uploaded.', array(
        '@filename' => $file->filename,
      )));
      $this
        ->assertUniqueText(t('Only files with the following extensions are allowed: .'));
      $this
        ->assertUniqueText(t('The file is @filesize exceeding the maximum file size of 1 KB.', array(
        '@filesize' => format_size(filesize($file->uri)),
      )));

      // Ensure that a 1 byte file can be attached, but will still be refused
      // because no allowed extensions have been set for the user's roles.
      $tinyfile_name = 'tinyfile.txt';
      file_put_contents('public://' . $tinyfile_name, '1');
      $this->message['files[contact_attach_1]'] = drupal_realpath('public://' . $tinyfile_name);
      $this
        ->drupalPost($contact_form, $this->message, t('Send message'));
      $this
        ->assertNoText(t('Your message has been sent.'));
      $this
        ->assertUniqueText(t('The specified file @filename could not be uploaded. Only files with the following extensions are allowed: .', array(
        '@filename' => $tinyfile_name,
      )));
    }
    if ($user) {
      $this
        ->drupalLogoutWithUserGlobalRolesUpdate();
    }
  }

  /**
   * Checks the number of attachment fields after setting the variable.
   *
   * @param int $rid
   *   The role ID of the role to be checked.
   * @param string $contact_attach_number
   *   The number of attachments to be allowed for the role defined in $rid.
   * @param object $user
   *   (optional) A fully-loaded $user object of the user to log in. Defaults to
   *   NULL.
   */
  function checkNumberOfAttachmentFields($rid, $contact_attach_number, $user = NULL) {
    if ($user) {
      $this
        ->drupalLoginWithUserGlobalRolesUpdate($user);
    }
    foreach ($this->contact_forms_short as $contact_form_short => $contact_form_path) {
      if ($contact_form_short === 'site') {
        $contact_form_permission = 'attach files on site-wide contact form';
      }
      elseif ($contact_form_short === 'user') {
        $contact_form_permission = 'attach files on personal contact forms';
      }
      $this->attachment_numbers[$rid] = $contact_attach_number;
      variable_set('contact_attach_number_' . $contact_form_short, $this->attachment_numbers);
      $roles = _contact_attach_get_valid_roles($contact_form_permission, $this->attachment_numbers);
      $attachments_allowed = _contact_attach_return_max_attachments($roles, $this->attachment_numbers);
      $this
        ->drupalGet($contact_form_path);
      $this
        ->assertRaw('files[contact_attach_' . $attachments_allowed . ']', $attachments_allowed . ' attachment fields appear on contact form.');
      $this
        ->assertNoRaw('files[contact_attach_' . ($attachments_allowed + 1) . ']', 'More than ' . $attachments_allowed . ' attachment fields do NOT appear on contact form.');
    }
    if ($user) {
      $this
        ->drupalLogoutWithUserGlobalRolesUpdate();
    }
  }

  /**
   * Submits contact forms with attachments after setting the settings.
   *
   * @param int $rid
   *   The role ID of the role.
   * @param string $extensions
   *   The extensions that will be set as allowed for the role.
   * @param string $uploadsize
   *   The maximum allowed file size that will be set for the role.
   * @param object $user
   *   (optional) A fully-loaded $user object of the user to log in. Defaults to
   *   NULL.
   */
  function submitWithAttachments($rid, $extensions, $uploadsize, $user = NULL) {
    if ($user) {
      $this
        ->drupalLoginWithUserGlobalRolesUpdate($user);
    }
    foreach ($this->contact_forms_short as $contact_form_short => $contact_form_path) {
      if ($contact_form_short === 'site') {
        $contact_form_permission = 'attach files on site-wide contact form';
        $mail_id = 'contact_page_mail';
        $mail_subject_start = '[Website feedback] ';
      }
      elseif ($contact_form_short === 'user') {
        $contact_form_permission = 'attach files on personal contact forms';
        $mail_id = 'contact_user_mail';
        $mail_subject_start = '[Drupal] ';
      }
      $this->extensions[$rid] = $extensions;
      $this->uploadsizes[$rid] = $uploadsize;
      variable_set('contact_attach_extensions_' . $contact_form_short, $this->extensions);
      variable_set('contact_attach_uploadsize_' . $contact_form_short, $this->uploadsizes);
      $contact_attach_numbers = variable_get('contact_attach_number_' . $contact_form_short, array());
      $roles = _contact_attach_get_valid_roles($contact_form_permission, $contact_attach_numbers);
      $allowed_extensions = _contact_attach_return_allowed_extensions($roles, $contact_form_short);
      $file_size_limit = _contact_attach_return_max_file_size($roles, $contact_form_short);
      $this->message['subject'] = 'Test message - ' . $this->file_field_type . ' - role ' . $rid;

      // Ensure that the user can not send messages with attachments when the
      // file depasses the maximum file size and the file does not have an
      // allowed extension.
      $filename = 'testfile1.txt';
      file_put_contents('public://' . $filename, $this
        ->randomString(1433));
      $this->message['files[contact_attach_1]'] = drupal_realpath('public://' . $filename);
      $this
        ->drupalPost($contact_form_path, $this->message, t('Send message'));
      $this
        ->assertNoText(t('Your message has been sent.'));
      $this
        ->assertUniqueText(t('The specified file @filename could not be uploaded.', array(
        '@filename' => $filename,
      )));
      $this
        ->assertUniqueText(t('Only files with the following extensions are allowed: @extensions.', array(
        '@extensions' => $allowed_extensions,
      )));
      $this
        ->assertUniqueText(t('The file is @filesize exceeding the maximum file size of @maxsize.', array(
        '@filesize' => format_size(filesize('public://' . $filename)),
        '@maxsize' => format_size($file_size_limit),
      )));

      // Ensure that a 1 byte file can be attached, but will still be refused
      // because it is not an allowed extension.
      $tinyfile_name = 'tinyfile.txt';
      file_put_contents('public://' . $tinyfile_name, '1');
      $this->message['files[contact_attach_1]'] = drupal_realpath('public://' . $tinyfile_name);
      $this
        ->drupalPost($contact_form_path, $this->message, t('Send message'));
      $this
        ->assertNoText(t('Your message has been sent.'));
      $this
        ->assertUniqueText(t('The specified file @filename could not be uploaded. Only files with the following extensions are allowed: @extensions.', array(
        '@filename' => $tinyfile_name,
        '@extensions' => $allowed_extensions,
      )));

      // Ensure that a file with an allowed extension can be attached, but will
      // still be refused as it depasses the maximum file size.
      $filename = 'testfile2.' . ltrim(substr($extensions, strrpos($extensions, ' ')));
      file_put_contents('public://' . $filename, $this
        ->randomString(1433));
      $this->message['files[contact_attach_1]'] = drupal_realpath('public://' . $filename);
      $this
        ->drupalPost($contact_form_path, $this->message, t('Send message'));
      $this
        ->assertNoText(t('Your message has been sent.'));
      $this
        ->assertUniqueText(t('The specified file @filename could not be uploaded. The file is @filesize exceeding the maximum file size of @maxsize.', array(
        '@filename' => $filename,
        '@filesize' => format_size(filesize('public://' . $filename)),
        '@maxsize' => format_size($file_size_limit),
      )));

      // Ensure that the user can send messages with attachments when the file
      // does not depass the maximum file size and the file has an allowed
      // extension.
      $file = new stdClass();
      $file->filename = 'testfile3-' . $contact_form_short . '.' . ltrim(substr($extensions, strrpos($extensions, ' ')));
      $file->uri = 'temporary://' . $file->filename;

      // Put the submitted file in another location so that file_save_upload()
      // does not rename its saved file because the filename already exists.
      file_put_contents('public://' . $file->filename, '1');
      $file->filemime = file_get_mimetype($file->filename);
      $this->message['files[contact_attach_1]'] = drupal_realpath('public://' . $file->filename);
      $this
        ->drupalPost($contact_form_path, $this->message, t('Send message'));

      // The file has been deleted in _contact_attach_add_attachment() after the
      // file was embedded, so we need to use the copy from now on.
      $file->uri = 'public://' . $file->filename;
      $this
        ->assertUniqueText(t('Your message has been sent.'));
      $this
        ->assertNoText(t('The specified file @filename could not be uploaded.', array(
        '@filename' => $file->filename,
      )));
      $this
        ->assertNoText(t('Only files with the following extensions are allowed: @extensions.', array(
        '@extensions' => $allowed_extensions,
      )));
      $this
        ->assertNoText(t('The file is @filesize exceeding the maximum file size of @maxsize.', array(
        '@filesize' => format_size(filesize($file->uri)),
        '@maxsize' => format_size($file_size_limit),
      )));

      // Verify that the mail was successfully sent and that the attachment is a
      // part of the body.
      $captured_email = $this
        ->drupalGetMails(array(
        'id' => $mail_id,
        'from' => $this->message['mail'],
        'subject' => $mail_subject_start . $this->message['subject'],
      ));
      $this
        ->assertEqual(count($captured_email), 1, 'One mail successfully sent.');
      list(, $boundary_id) = explode('"', $captured_email[0]['headers']['Content-Type']);
      $this
        ->assertEqual(substr_count($captured_email[0]['body'], $boundary_id), 3, 'Boundary ID appears 3 times in the sent message.');
      $attachment = "--{$boundary_id}\n" . _contact_attach_add_attachment($file, array(), FALSE) . "\n\n--{$boundary_id}--\n";

      // chunk_split() uses \r\n as line ending sequence by default, but a mail
      // function removes \r, so we must do the same for the comparison to work.
      $attachment = str_replace("\r\n", "\n", $attachment);
      $this
        ->assertEqual(strstr($captured_email[0]['body'], $attachment), $attachment, 'Attachment exists in the body of the sent message.');
    }
    if ($user) {
      $this
        ->drupalLogoutWithUserGlobalRolesUpdate();
    }
  }

  /**
   * Logs in a user with the internal browser and updates the $user global.
   *
   * drupalLogin() does not update the $user global after logging in. This
   * function populates $user->roles with the roles defined in the user object.
   *
   * @param stdClass $user_object
   *   User object representing the user to log in.
   */
  function drupalLoginWithUserGlobalRolesUpdate(stdClass $user_object) {
    global $user;
    $this
      ->drupalLogin($user_object);
    $user->roles = $user_object->roles;
  }

  /**
   * Logs out a user with the internal browser and updates the $user global.
   *
   * drupalLogout() does not update the $user global after logging out. This
   * function populates $user->roles with the anonymous role.
   */
  function drupalLogoutWithUserGlobalRolesUpdate() {
    global $user;
    $this
      ->drupalLogout();
    $user->roles = array(
      DRUPAL_ANONYMOUS_RID => 'anonymous user',
    );
  }

  /**
   * Resets all of the module's persistent variables and users' permissions.
   */
  function resetPersistentVariablesAndPermissions() {

    // Reset all persistent variables for the next run.
    variable_del('contact_attach_simple_field');
    variable_del('contact_attach_extensions_site');
    variable_del('contact_attach_extensions_user');
    variable_del('contact_attach_number_site');
    variable_del('contact_attach_number_user');
    variable_del('contact_attach_uploadsize_site');
    variable_del('contact_attach_uploadsize_user');

    // Revoke all module permissions for the next run.
    user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array_values($this->contact_forms));
    user_role_revoke_permissions(DRUPAL_AUTHENTICATED_RID, array_values($this->contact_forms));
    user_role_revoke_permissions($this->created_role_rid, array_values($this->contact_forms));
    user_role_revoke_permissions($this->created_role_2_rid, array_values($this->contact_forms));
  }

}

Classes

Namesort descending Description
ContactAttachContactFormsTestCase Tests the Contact Attach functionality for site-wide and user contact forms.
ContactAttachSettingsFormTestCase Tests the Contact Attach settings form.