Tests: Add decorators to PHPMailer mock object.

The new `get_recipient()` and `get_sent()` methods greatly simplify the
syntax required when writing tests for `wp_mail()`.

Props welcher.
Fixes #34161.

git-svn-id: https://develop.svn.wordpress.org/trunk@36594 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2016-02-20 03:40:49 +00:00
parent 6779bd5734
commit c43fc5ac2b
3 changed files with 159 additions and 81 deletions

View File

@ -14,13 +14,73 @@ class MockPHPMailer extends PHPMailer {
*/
function postSend() {
$this->mock_sent[] = array(
'to' => $this->to,
'cc' => $this->cc,
'bcc' => $this->bcc,
'header' => $this->MIMEHeader,
'body' => $this->MIMEBody,
'to' => $this->to,
'cc' => $this->cc,
'bcc' => $this->bcc,
'header' => $this->MIMEHeader,
'subject' => $this->Subject,
'body' => $this->MIMEBody,
);
return true;
}
/**
* Decorator to return the information for a sent mock.
*
* @since 4.5.0
*
* @param int $index Optional. Array index of mock_sent value.
* @return object
*/
public function get_sent( $index = 0 ) {
$retval = false;
if ( isset( $this->mock_sent[ $index ] ) ) {
$retval = (object) $this->mock_sent[ $index ];
}
return $retval;
}
/**
* Get a recipient for a sent mock.
*
* @since 4.5.0
*
* @param string $address_type The type of address for the email such as to, cc or bcc.
* @param int $mock_sent_index Optional. The sent_mock index we want to get the recipient for.
* @param int $recipient_index Optional. The recipient index in the array.
* @return bool|object Returns object on success, or false if any of the indices don't exist.
*/
public function get_recipient( $address_type, $mock_sent_index = 0, $recipient_index = 0 ) {
$retval = false;
$mock = $this->get_sent( $mock_sent_index );
if ( $mock ) {
if ( isset( $mock->{$address_type}[ $recipient_index ] ) ) {
$address_index = $mock->{$address_type}[ $recipient_index ];
$recipient_data = array(
'address' => ( isset( $address_index[0] ) && ! empty( $address_index[0] ) ) ? $address_index[0] : 'No address set',
'name' => ( isset( $address_index[1] ) && ! empty( $address_index[1] ) ) ? $address_index[1] : 'No name set',
);
$retval = (object) $recipient_data;
}
}
return $retval;
}
}
/**
* Helper method to return the global phpmailer instance defined in the bootstrap
*
* @since 4.4.0
*
* @return object|bool
*/
function tests_retrieve_phpmailer_instance() {
$mailer = false;
if ( isset( $GLOBALS['phpmailer'] ) ) {
$mailer = $GLOBALS['phpmailer'];
}
return $mailer;
}

View File

@ -71,24 +71,26 @@ class Tests_Mail extends WP_UnitTestCase {
$body .= '------=_Part_4892_25692638.1192452070893--' . "\n";
$body .= "\n";
wp_mail($to, $subject, $body, $headers);
wp_mail( $to, $subject, $body, $headers );
$mailer = tests_retrieve_phpmailer_instance();
// We need some better assertions here but these catch the failure for now.
$this->assertEquals($body, $GLOBALS['phpmailer']->mock_sent[0]['body']);
$this->assertTrue(strpos($GLOBALS['phpmailer']->mock_sent[0]['header'], 'boundary="----=_Part_4892_25692638.1192452070893"') > 0);
$this->assertTrue(strpos($GLOBALS['phpmailer']->mock_sent[0]['header'], 'charset=') > 0);
$this->assertEquals( $body, $mailer->get_sent()->body );
$this->assertTrue( strpos( $mailer->get_sent()->header, 'boundary="----=_Part_4892_25692638.1192452070893"' ) > 0 );
$this->assertTrue( strpos( $mailer->get_sent()->header, 'charset=' ) > 0 );
}
/**
* @ticket 17305
*/
function test_wp_mail_rfc2822_addresses() {
$to = "Name <address@tld.com>";
$from = "Another Name <another_address@different-tld.com>";
$cc = "The Carbon Guy <cc@cc.com>";
$bcc = "The Blind Carbon Guy <bcc@bcc.com>";
$subject = "RFC2822 Testing";
$message = "My RFC822 Test Message";
$to = 'Name <address@tld.com>';
$from = 'Another Name <another_address@different-tld.com>';
$cc = 'The Carbon Guy <cc@cc.com>';
$bcc = 'The Blind Carbon Guy <bcc@bcc.com>';
$subject = 'RFC2822 Testing';
$message = 'My RFC822 Test Message';
$headers[] = "From: {$from}";
$headers[] = "CC: {$cc}";
$headers[] = "BCC: {$bcc}";
@ -97,58 +99,64 @@ class Tests_Mail extends WP_UnitTestCase {
// WordPress 3.2 and later correctly split the address into the two parts and send them seperately to PHPMailer
// Earlier versions of PHPMailer were not touchy about the formatting of these arguments.
$this->assertEquals('address@tld.com', $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0]);
$this->assertEquals('Name', $GLOBALS['phpmailer']->mock_sent[0]['to'][0][1]);
$this->assertEquals('cc@cc.com', $GLOBALS['phpmailer']->mock_sent[0]['cc'][0][0]);
$this->assertEquals('The Carbon Guy', $GLOBALS['phpmailer']->mock_sent[0]['cc'][0][1]);
$this->assertEquals('bcc@bcc.com', $GLOBALS['phpmailer']->mock_sent[0]['bcc'][0][0]);
$this->assertEquals('The Blind Carbon Guy', $GLOBALS['phpmailer']->mock_sent[0]['bcc'][0][1]);
$this->assertEquals($message . "\n", $GLOBALS['phpmailer']->mock_sent[0]['body']);
//retrieve the mailer instance
$mailer = tests_retrieve_phpmailer_instance();
$this->assertEquals( 'address@tld.com', $mailer->get_recipient( 'to' )->address );
$this->assertEquals( 'Name', $mailer->get_recipient( 'to' )->name );
$this->assertEquals( 'cc@cc.com', $mailer->get_recipient( 'cc' )->address );
$this->assertEquals( 'The Carbon Guy', $mailer->get_recipient( 'cc' )->name );
$this->assertEquals( 'bcc@bcc.com', $mailer->get_recipient( 'bcc' )->address );
$this->assertEquals( 'The Blind Carbon Guy', $mailer->get_recipient( 'bcc' )->name );
$this->assertEquals( $message . "\n", $mailer->get_sent()->body );
}
/**
* @ticket 17305
*/
function test_wp_mail_multiple_rfc2822_to_addresses() {
$to = "Name <address@tld.com>, Another Name <another_address@different-tld.com>";
$subject = "RFC2822 Testing";
$message = "My RFC822 Test Message";
$to = 'Name <address@tld.com>, Another Name <another_address@different-tld.com>';
$subject = 'RFC2822 Testing';
$message = 'My RFC822 Test Message';
wp_mail( $to, $subject, $message );
// WordPress 3.2 and later correctly split the address into the two parts and send them seperately to PHPMailer
// Earlier versions of PHPMailer were not touchy about the formatting of these arguments.
$this->assertEquals('address@tld.com', $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0]);
$this->assertEquals('Name', $GLOBALS['phpmailer']->mock_sent[0]['to'][0][1]);
$this->assertEquals('another_address@different-tld.com', $GLOBALS['phpmailer']->mock_sent[0]['to'][1][0]);
$this->assertEquals('Another Name', $GLOBALS['phpmailer']->mock_sent[0]['to'][1][1]);
$this->assertEquals($message . "\n", $GLOBALS['phpmailer']->mock_sent[0]['body']);
$mailer = tests_retrieve_phpmailer_instance();
$this->assertEquals( 'address@tld.com', $mailer->get_recipient( 'to' )->address );
$this->assertEquals( 'Name', $mailer->get_recipient( 'to' )->name );
$this->assertEquals( 'another_address@different-tld.com', $mailer->get_recipient( 'to', 0, 1 )->address );
$this->assertEquals( 'Another Name', $mailer->get_recipient( 'to', 0, 1 )->name );
$this->assertEquals( $message . "\n", $mailer->get_sent()->body );
}
function test_wp_mail_multiple_to_addresses() {
$to = "address@tld.com, another_address@different-tld.com";
$subject = "RFC2822 Testing";
$message = "My RFC822 Test Message";
$to = 'address@tld.com, another_address@different-tld.com';
$subject = 'RFC2822 Testing';
$message = 'My RFC822 Test Message';
wp_mail( $to, $subject, $message );
$this->assertEquals('address@tld.com', $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0]);
$this->assertEquals('another_address@different-tld.com', $GLOBALS['phpmailer']->mock_sent[0]['to'][1][0]);
$this->assertEquals($message . "\n", $GLOBALS['phpmailer']->mock_sent[0]['body']);
$mailer = tests_retrieve_phpmailer_instance();
$this->assertEquals( 'address@tld.com', $mailer->get_recipient( 'to' )->address );
$this->assertEquals( 'another_address@different-tld.com', $mailer->get_recipient( 'to', 0, 1 )->address );
$this->assertEquals( $message . "\n", $mailer->get_sent()->body );
}
/**
* @ticket 18463
*/
function test_wp_mail_to_address_no_name() {
$to = "<address@tld.com>";
$subject = "RFC2822 Testing";
$message = "My RFC822 Test Message";
$to = '<address@tld.com>';
$subject = 'RFC2822 Testing';
$message = 'My RFC822 Test Message';
wp_mail( $to, $subject, $message );
$this->assertEquals('address@tld.com', $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0]);
$this->assertEquals($message . "\n", $GLOBALS['phpmailer']->mock_sent[0]['body']);
$mailer = tests_retrieve_phpmailer_instance();
$this->assertEquals( 'address@tld.com', $mailer->get_recipient( 'to' )->address );
$this->assertEquals( $message . "\n", $mailer->get_sent()->body );
}
/**
@ -169,90 +177,96 @@ class Tests_Mail extends WP_UnitTestCase {
* @ticket 30266
*/
public function test_wp_mail_with_valid_from_header() {
$to = "address@tld.com";
$subject = "Testing";
$message = "Test Message";
$headers = "From: Foo <bar@example.com>";
$expected = "From: Foo <bar@example.com>";
$to = 'address@tld.com';
$subject = 'Testing';
$message = 'Test Message';
$headers = 'From: Foo <bar@example.com>';
$expected = 'From: Foo <bar@example.com>';
wp_mail( $to, $subject, $message, $headers );
$this->assertTrue( strpos( $GLOBALS['phpmailer']->mock_sent[0]['header'], $expected ) > 0 );
$mailer = tests_retrieve_phpmailer_instance();
$this->assertTrue( strpos( $mailer->get_sent()->header, $expected ) > 0 );
}
/**
* @ticket 30266
*/
public function test_wp_mail_with_empty_from_header() {
$to = "address@tld.com";
$subject = "Testing";
$message = "Test Message";
$headers = "From: ";
$expected = "From: WordPress <wordpress@" . WP_TESTS_DOMAIN . ">";
$to = 'address@tld.com';
$subject = 'Testing';
$message = 'Test Message';
$headers = 'From: ';
$expected = 'From: WordPress <wordpress@' . WP_TESTS_DOMAIN . '>';
wp_mail( $to, $subject, $message, $headers );
$this->assertTrue( strpos( $GLOBALS['phpmailer']->mock_sent[0]['header'], $expected ) > 0 );
$mailer = tests_retrieve_phpmailer_instance();
$this->assertTrue( strpos( $mailer->get_sent()->header, $expected ) > 0 );
}
/**
* @ticket 30266
*/
public function test_wp_mail_with_empty_from_name_for_the_from_header() {
$to = "address@tld.com";
$subject = "Testing";
$message = "Test Message";
$headers = "From: <wordpress@example.com>";
$expected = "From: WordPress <wordpress@example.com>";
$to = 'address@tld.com';
$subject = 'Testing';
$message = 'Test Message';
$headers = 'From: <wordpress@example.com>';
$expected = 'From: WordPress <wordpress@example.com>';
wp_mail( $to, $subject, $message, $headers );
$this->assertTrue( strpos( $GLOBALS['phpmailer']->mock_sent[0]['header'], $expected ) > 0 );
$mailer = tests_retrieve_phpmailer_instance();
$this->assertTrue( strpos( $mailer->get_sent()->header, $expected ) > 0 );
}
/**
* @ticket 30266
*/
public function test_wp_mail_with_valid_content_type_header() {
$to = "address@tld.com";
$subject = "Testing";
$message = "Test Message";
$headers = "Content-Type: text/html; charset=iso-8859-1";
$expected = "Content-Type: text/html; charset=iso-8859-1";
$to = 'address@tld.com';
$subject = 'Testing';
$message = 'Test Message';
$headers = 'Content-Type: text/html; charset=iso-8859-1';
$expected = 'Content-Type: text/html; charset=iso-8859-1';
wp_mail( $to, $subject, $message, $headers );
$this->assertTrue( strpos( $GLOBALS['phpmailer']->mock_sent[0]['header'], $expected ) > 0 );
$mailer = tests_retrieve_phpmailer_instance();
$this->assertTrue( strpos( $mailer->get_sent()->header, $expected ) > 0 );
}
/**
* @ticket 30266
*/
public function test_wp_mail_with_empty_content_type_header() {
$to = "address@tld.com";
$subject = "Testing";
$message = "Test Message";
$headers = "Content-Type: ";
$expected = "Content-Type: text/plain; charset=UTF-8";
$to = 'address@tld.com';
$subject = 'Testing';
$message = 'Test Message';
$headers = 'Content-Type: ';
$expected = 'Content-Type: text/plain; charset=UTF-8';
wp_mail( $to, $subject, $message, $headers );
$this->assertTrue( strpos( $GLOBALS['phpmailer']->mock_sent[0]['header'], $expected ) > 0 );
$mailer = tests_retrieve_phpmailer_instance();
$this->assertTrue( strpos( $mailer->get_sent()->header, $expected ) > 0 );
}
/**
* @ticket 30266
*/
public function test_wp_mail_with_empty_charset_for_the_content_type_header() {
$to = "address@tld.com";
$subject = "Testing";
$message = "Test Message";
$headers = "Content-Type: text/plain;";
$expected = "Content-Type: text/plain; charset=UTF-8";
$to = 'address@tld.com';
$subject = 'Testing';
$message = 'Test Message';
$headers = 'Content-Type: text/plain;';
$expected = 'Content-Type: text/plain; charset=UTF-8';
wp_mail( $to, $subject, $message, $headers );
$this->assertTrue( strpos( $GLOBALS['phpmailer']->mock_sent[0]['header'], $expected ) > 0 );
$mailer = tests_retrieve_phpmailer_instance();
$this->assertTrue( strpos( $mailer->get_sent()->header, $expected ) > 0 );
}
function wp_mail_quoted_printable( $mailer ) {

View File

@ -1028,14 +1028,18 @@ class Tests_User extends WP_UnitTestCase {
wp_new_user_notification( self::$contrib_id, null, $notify );
$mailer = tests_retrieve_phpmailer_instance();
/*
* Check to see if a notification email was sent to the
* post author `blackburn@battlefield3.com` and and site admin `admin@example.org`.
*/
if ( ! empty( $GLOBALS['phpmailer']->mock_sent ) ) {
$was_admin_email_sent = ( isset( $GLOBALS['phpmailer']->mock_sent[0] ) && WP_TESTS_EMAIL == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0] );
$was_user_email_sent = ( isset( $GLOBALS['phpmailer']->mock_sent[1] ) && 'blackburn@battlefield3.com' == $GLOBALS['phpmailer']->mock_sent[1]['to'][0][0] );
}
$admin_email = $mailer->get_recipient( 'to' );
$was_admin_email_sent = $admin_email && WP_TESTS_EMAIL === $admin_email->address;
$user_email = $mailer->get_recipient( 'to', 1 );
$was_user_email_sent = $user_email && 'blackburn@battlefield3.com' == $user_email->address;
$this->assertSame( $admin_email_sent_expected, $was_admin_email_sent, 'Admin email result was not as expected in test_wp_new_user_notification' );
$this->assertSame( $user_email_sent_expected , $was_user_email_sent, 'User email result was not as expected in test_wp_new_user_notification' );