'Mail system', 'description' => 'Performs tests on the pluggable mailing framework.', 'group' => 'System', ); } function setUp() { parent::setUp(array('simpletest')); // Set MailTestCase (i.e. this class) as the SMTP library variable_set('mail_system', array('default-system' => 'MailTestCase')); } /** * Assert that the pluggable mail system is functional. */ function testPluggableFramework() { global $language; // Use MailTestCase for sending a message. $message = drupal_mail('simpletest', 'mail_test', 'testing@example.com', $language); // Assert whether the message was sent through the send function. $this->assertEqual(self::$sent_message['to'], 'testing@example.com', 'Pluggable mail system is extendable.'); } /** * Test that message sending may be canceled. * * @see simpletest_mail_alter() */ function testCancelMessage() { global $language; // Reset the class variable holding a copy of the last sent message. self::$sent_message = NULL; // Send a test message that simpletest_mail_alter should cancel. $message = drupal_mail('simpletest', 'cancel_test', 'cancel@example.com', $language); // Assert that the message was not actually sent. $this->assertNull(self::$sent_message, 'Message was canceled.'); } /** * Checks for the site name in an auto-generated From: header. */ function testFromHeader() { global $language; $default_from = variable_get('site_mail', ini_get('sendmail_from')); $site_name = variable_get('site_name', 'Drupal'); // Reset the class variable holding a copy of the last sent message. self::$sent_message = NULL; // Send an e-mail with a sender address specified. $from_email = 'someone_else@example.com'; $message = drupal_mail('simpletest', 'from_test', 'from_test@example.com', $language, array(), $from_email); // Test that the from e-mail is just the e-mail and not the site name and // default sender e-mail. $this->assertEqual($from_email, self::$sent_message['headers']['From']); // Check default behavior is only email in FROM header. self::$sent_message = NULL; // Send an e-mail and check that the From-header contains only default mail address. variable_del('mail_display_name_site_name'); $message = drupal_mail('simpletest', 'from_test', 'from_test@example.com', $language); $this->assertEqual($default_from, self::$sent_message['headers']['From']); self::$sent_message = NULL; // Send an e-mail and check that the From-header contains the site name. variable_set('mail_display_name_site_name', TRUE); $message = drupal_mail('simpletest', 'from_test', 'from_test@example.com', $language); $this->assertEqual($site_name . ' <' . $default_from . '>', self::$sent_message['headers']['From']); } /** * Checks for the site name in an auto-generated From: header. */ function testFromHeaderRfc2822Compliant() { global $language; $default_from = variable_get('site_mail', ini_get('sendmail_from')); // Enable adding a site name to From. variable_set('mail_display_name_site_name', TRUE); $site_names = array( // Simple ASCII characters. 'Test site' => 'Test site', // ASCII with html entity. 'Test & site' => 'Test & site', // Non-ASCII characters. 'Tést site' => '=?UTF-8?B?VMOpc3Qgc2l0ZQ==?=', // Non-ASCII with special characters. 'Tést; site' => '=?UTF-8?B?VMOpc3Q7IHNpdGU=?=', // Non-ASCII with html entity. 'Tést; site' => '=?UTF-8?B?VMOpc3Q7IHNpdGU=?=', // ASCII with special characters. 'Test; site' => '"Test; site"', // ASCII with special characters as html entity. 'Test < site' => '"Test < site"', // ASCII with special characters and '\'. 'Test; \ "site"' => '"Test; \\\\ \"site\""', // String already RFC-2822 compliant. '"Test; site"' => '"Test; site"', // String already RFC-2822 compliant. '"Test; \\\\ \"site\""' => '"Test; \\\\ \"site\""', ); foreach ($site_names as $original_name => $safe_string) { variable_set('site_name', $original_name); // Reset the class variable holding a copy of the last sent message. self::$sent_message = NULL; // Send an e-mail and check that the From-header contains is RFC-2822 compliant. drupal_mail('simpletest', 'from_test', 'from_test@example.com', $language); $this->assertEqual($safe_string . ' <' . $default_from . '>', self::$sent_message['headers']['From']); } } /** * Concatenate and wrap the e-mail body for plain-text mails. * * @see DefaultMailSystem */ public function format(array $message) { // Join the body array into one string. $message['body'] = implode("\n\n", $message['body']); // Convert any HTML to plain-text. $message['body'] = drupal_html_to_text($message['body']); // Wrap the mail body for sending. $message['body'] = drupal_wrap_mail($message['body']); return $message; } /** * Send function that is called through the mail system. */ public function mail(array $message) { self::$sent_message = $message; } } /** * Unit tests for drupal_html_to_text(). */ class DrupalHtmlToTextTestCase extends DrupalWebTestCase { public static function getInfo() { return array( 'name' => 'HTML to text conversion', 'description' => 'Tests drupal_html_to_text().', 'group' => 'Mail', ); } /** * Converts a string to its PHP source equivalent for display in test messages. * * @param $text * The text string to convert. * * @return * An HTML representation of the text string that, when displayed in a * browser, represents the PHP source code equivalent of $text. */ function stringToHtml($text) { return '"' . str_replace( array("\n", ' '), array('\n', ' '), check_plain($text) ) . '"'; } /** * Helper function for testing drupal_html_to_text(). * * @param $html * The source HTML string to be converted. * @param $text * The expected result of converting $html to text. * @param $message * A text message to display in the assertion message. * @param $allowed_tags * (optional) An array of allowed tags, or NULL to default to the full * set of tags supported by drupal_html_to_text(). */ function assertHtmlToText($html, $text, $message, $allowed_tags = NULL) { preg_match_all('/<([a-z0-6]+)/', drupal_strtolower($html), $matches); $tested_tags = implode(', ', array_unique($matches[1])); $message .= ' (' . $tested_tags . ')'; $result = drupal_html_to_text($html, $allowed_tags); $pass = $this->assertEqual($result, $text, check_plain($message)); $verbose = 'html =
' . $this->stringToHtml($html) . '
' . $this->stringToHtml($result) . '
' . $this->stringToHtml($text) . ''; $this->verbose($verbose); if (!$pass) { $this->pass("Previous test verbose info:
Drupal' => ">Drupal\n", '
Drupal
Drupal' => ">Drupal\n>Drupal\n", '
Drupal
' => "Drupal\nDrupal\nDrupal\nDrupal\n\n", 'Drupal
' => "======== DRUPAL ==============================================================\n\nDrupal\n\n", 'Drupal
' => "-------- DRUPAL --------------------------------------------------------------\n\nDrupal\n\n", 'Drupal
' => ".... Drupal\n\nDrupal\n\n", 'Drupal
' => ".. Drupal\n\nDrupal\n\n", 'Drupal
' => "Drupal\n\nDrupal\n\n", 'Drupal
' => "Drupal\n\nDrupal\n\n", 'Drupal
' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\nDrupal\n\n", 'Drupal' => "/Drupal/\n", 'Drupal
' => "Drupal\n\n", 'Drupal
Drupal
' => "Drupal\n\nDrupal\n\n", 'Drupal' => "*Drupal*\n", // @todo Tables are currently not supported. 'Drupal | Drupal |
Drupal | Drupal |
Drupal |
Drupal
' => "Drupal\nDrupal\n\n", // @todo The tag is currently not supported. 'Drupal' => "Drupal\n", 'Drupal
' => " * Drupal\n\nDrupal\n\n", 'Drupal
' => " 1) Drupal\n\nDrupal\n\n", 'Drupal
' => "Drupal\n Drupal\n\nDrupal\n\n", 'Drupal
' => "Drupal\n\nDrupal\n\n", // @todo Again, lines containing only spaces should be trimmed. 'Drupal
' => "Drupal\n\nDrupal\n\n", 'Drupal
Drupal', "Drupal Drupal Drupal\n", 'Disallowed
, , and tags not found',
array('a', 'br', 'h1')
);
$this->assertHtmlToText(
'Drupal',
"Drupal\n",
'Unsupported and tags not found',
array('html', 'body')
);
}
/**
* Tests that drupal_wrap_mail() removes trailing whitespace before newlines.
*/
function testDrupalHtmltoTextRemoveTrailingWhitespace() {
$text = "Hi there! \nHerp Derp";
$mail_lines = explode("\n", drupal_wrap_mail($text));
$this->assertNotEqual(" ", substr($mail_lines[0], -1), 'Trailing whitespace removed.');
}
/**
* Tests drupal_wrap_mail() retains whitespace from Usenet style signatures.
*
* RFC 3676 says, "This is a special case; an (optionally quoted or quoted and
* stuffed) line consisting of DASH DASH SP is neither fixed nor flowed."
*/
function testDrupalHtmltoTextUsenetSignature() {
$text = "Hi there!\n-- \nHerp Derp";
$mail_lines = explode("\n", drupal_wrap_mail($text));
$this->assertEqual("-- ", $mail_lines[1], 'Trailing whitespace not removed for dash-dash-space signatures.');
$text = "Hi there!\n-- \nHerp Derp";
$mail_lines = explode("\n", drupal_wrap_mail($text));
$this->assertEqual("--", $mail_lines[1], 'Trailing whitespace removed for incorrect dash-dash-space signatures.');
}
/**
* Test that whitespace is collapsed.
*/
function testDrupalHtmltoTextCollapsesWhitespace() {
$input = " Drupal Drupal\n\nDrupalDrupal Drupal\n\nDrupal
Drupal Drupal\n\nDrupal
[blockquote]' . '
[p]
' . 'Drupal
Drupal
'; // @todo There should be more space above the header than below it. $text = "Drupal\n======== DRUPAL ==============================================================\n\nDrupal\n\n"; $this->assertHtmlToText($html, $text, 'Text before and paragraph afterDrupal
Drupal
'; $text = "Drupal\n\n======== DRUPAL ==============================================================\n\nDrupal\n\n"; $this->assertHtmlToText($html, $text, 'Paragraph before and afterline 1
\nline 2
line 3\n
line 4
paragraph
", // @todo Trailing line breaks should be trimmed. 'text' => "line 1\nline 2\nline 3\nline 4\n\nparagraph\n\n", ); $tests[] = array( 'html' => "line 1
line 2
line 4
line 5
0
", // @todo Trailing line breaks should be trimmed. 'text' => "line 1\nline 2\n\nline 4\nline 5\n\n0\n\n", ); foreach ($tests as $test) { $this->assertHtmlToText($test['html'], $test['text'], 'Paragraph breaks'); } } /** * Tests that drupal_html_to_text() wraps before 1000 characters. * * RFC 3676 says, "The Text/Plain media type is the lowest common * denominator of Internet email, with lines of no more than 998 characters." * * RFC 2046 says, "SMTP [RFC-821] allows a maximum of 998 octets before the * next CRLF sequence." * * RFC 821 says, "The maximum total length of a text line including the *' . str_repeat('x', 2100) . '