-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Adding interacts with mail to allow for easy testing against mail * CHANGELOG * Add assertMailSentCount() * PHPCS fix * Testing CI * Testing CI * Testing CI
- Loading branch information
Showing
9 changed files
with
279 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
src/mantle/testing/concerns/trait-interacts-with-mail.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<?php | ||
/** | ||
* Interacts_With_Mail trait file. | ||
* | ||
* @package Mantle | ||
* | ||
* @phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid | ||
*/ | ||
|
||
namespace Mantle\Testing\Concerns; | ||
|
||
use Mantle\Support\Collection; | ||
use Mantle\Testing\Doubles\MockPHPMailer; | ||
use Mantle\Testing\Mail\Mail_Message; | ||
use Mantle\Testing\Mail\Mock_Mailer; | ||
|
||
use function Mantle\Support\Helpers\collect; | ||
|
||
/** | ||
* Concern for interacting with the WordPress wp_mail() function. | ||
* | ||
* @mixin \Mantle\Testing\Test_Case | ||
*/ | ||
trait Interacts_With_Mail { | ||
/** | ||
* Setup the trait and replace the global phpmailer instance with a mock instance. | ||
*/ | ||
public function interacts_with_mail_set_up(): void { | ||
reset_phpmailer_instance(); | ||
} | ||
|
||
/** | ||
* Assert that an email was sent to the given recipient. | ||
* | ||
* @param (callable(\Mantle\Testing\Mail\Mail_Message): bool)|string|null $address_or_callback The email address to check for, or a callback to perform custom assertions. | ||
*/ | ||
public function assertMailSent( string|callable|null $address_or_callback = null ): void { | ||
$mailer = tests_retrieve_phpmailer_instance(); | ||
|
||
if ( ! ( $mailer instanceof Mock_Mailer ) ) { | ||
$this->fail( 'Mail instance is not a MockPHPMailer instance.' ); | ||
} | ||
|
||
if ( is_null( $address_or_callback ) ) { | ||
$this->assertNotEmpty( $mailer->mock_sent, 'No emails were sent.' ); | ||
return; | ||
} | ||
|
||
$this->assertNotEmpty( | ||
$this->getSentMail( $address_or_callback ), | ||
is_string( $address_or_callback ) ? "No email was sent to [{$address_or_callback}]." : 'No email was sent matching the given callback function.' | ||
); | ||
} | ||
|
||
/** | ||
* Assert that an email was not sent to the given recipient. | ||
* | ||
* @param (callable(\Mantle\Testing\Mail\Mail_Message): bool)|string|null $address_or_callback The email address to check for, or a callback to perform custom assertions. | ||
*/ | ||
public function assertMailNotSent( string|callable|null $address_or_callback = null ): void { | ||
$mailer = tests_retrieve_phpmailer_instance(); | ||
|
||
if ( ! ( $mailer instanceof Mock_Mailer ) ) { | ||
$this->fail( 'Mail instance is not a MockPHPMailer instance.' ); | ||
} | ||
|
||
if ( is_null( $address_or_callback ) ) { | ||
$this->assertEmpty( $mailer->mock_sent, 'An email was sent.' ); | ||
return; | ||
} | ||
|
||
$this->assertEmpty( | ||
$this->getSentMail( $address_or_callback ), | ||
is_string( $address_or_callback ) ? "An email was sent to [{$address_or_callback}]." : 'An email was sent matching the given callback function.' | ||
); | ||
} | ||
|
||
/** | ||
* Assert that a specific number of emails were sent. | ||
* | ||
* @param int $expected_count The expected number of emails sent. | ||
* @param (callable(\Mantle\Testing\Mail\Mail_Message): bool)|string|null $address_or_callback The email address to check for, or a callback to perform custom assertions. | ||
*/ | ||
public function assertMailSentCount( int $expected_count, string|callable|null $address_or_callback = null ): void { | ||
$mailer = tests_retrieve_phpmailer_instance(); | ||
|
||
if ( ! ( $mailer instanceof Mock_Mailer ) ) { | ||
$this->fail( 'Mail instance is not a MockPHPMailer instance.' ); | ||
} | ||
|
||
if ( is_null( $address_or_callback ) ) { | ||
$actual = count( $mailer->mock_sent ); | ||
$this->assertCount( $expected_count, $mailer->mock_sent, "Expected {$expected_count} emails to be sent, but only {$actual} were sent." ); | ||
return; | ||
} | ||
|
||
$sent_mail = $this->getSentMail( $address_or_callback ); | ||
$count = count( $sent_mail ); | ||
|
||
$this->assertCount( $expected_count, $sent_mail, "Expected {$expected_count} emails to be sent, but only {$count} were sent." ); | ||
} | ||
|
||
/** | ||
* Retrieve the sent mail for a given to address or callback function that | ||
* performs a match against sent mail. | ||
* | ||
* @param (callable(\Mantle\Testing\Mail\Mail_Message): bool)|string $address_or_callback The email address to check for, or a callback to perform custom assertions. | ||
* @return Collection<int, \Mantle\Testing\Mail\Mail_Message> | ||
*/ | ||
protected function getSentMail( string|callable $address_or_callback = null ): Collection { | ||
$mailer = tests_retrieve_phpmailer_instance(); | ||
|
||
if ( ! ( $mailer instanceof Mock_Mailer ) ) { | ||
$this->fail( 'Mail instance is not a MockPHPMailer instance.' ); | ||
} | ||
|
||
return collect( $mailer->mock_sent )->filter( | ||
function ( Mail_Message $message ) use ( $address_or_callback ) { | ||
if ( is_string( $address_or_callback ) ) { | ||
return $message->sent_to( $address_or_callback ); | ||
} | ||
|
||
return $address_or_callback( $message ); | ||
} | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
/** | ||
* Mail_Message class file | ||
* | ||
* @package Mantle | ||
*/ | ||
|
||
namespace Mantle\Testing\Mail; | ||
|
||
use function Mantle\Support\Helpers\collect; | ||
|
||
/** | ||
* Mail Message Record | ||
*/ | ||
class Mail_Message { | ||
/** | ||
* Constructor. | ||
* | ||
* @param array $to The recipient of the email. | ||
* @param array $cc The CC recipient of the email. | ||
* @param array $bcc The BCC recipient of the email. | ||
* @param string $subject The subject of the email. | ||
* @param string $body The body of the email. | ||
* @param string $header The header of the email. | ||
*/ | ||
public function __construct( | ||
public readonly array $to, | ||
public readonly array $cc, | ||
public readonly array $bcc, | ||
public readonly string $subject, | ||
public readonly string $body, | ||
public readonly string $header | ||
) {} | ||
|
||
/** | ||
* Check if the email was sent to the given recipient. | ||
* | ||
* @param string $address The email address to check for. | ||
* @return bool | ||
*/ | ||
public function sent_to( string $address ): bool { | ||
return collect( $this->to )->pluck( 0 )->contains( $address ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
/** | ||
* Mail helper methods. | ||
* | ||
* Intentionally not namespaced to mirror core. | ||
* | ||
* phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | ||
* phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited | ||
* | ||
* @package Mantle | ||
*/ | ||
|
||
use Mantle\Testing\Mail\Mock_Mailer; | ||
|
||
/** | ||
* Helper method to return the global phpmailer instance defined in the bootstrap | ||
* | ||
* @return \PHPMailer\PHPMailer\PHPMailer|bool | ||
*/ | ||
function tests_retrieve_phpmailer_instance(): \PHPMailer\PHPMailer\PHPMailer|bool { | ||
return $GLOBALS['phpmailer'] ?? false; | ||
} | ||
|
||
/** | ||
* Helper method to reset the phpmailer instance. | ||
*/ | ||
function reset_phpmailer_instance(): void { | ||
$GLOBALS['phpmailer'] = new Mock_Mailer( true ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.