diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index a781440..97f8b52 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -32,5 +32,6 @@ jobs: with: folder: php project: ${{ github.event.repository.name }} - secrets: inherit + secrets: + DOC_TOKEN: ${{ secrets.DOC_TOKEN }} diff --git a/README.md b/README.md index 49e563b..429d85f 100644 --- a/README.md +++ b/README.md @@ -104,13 +104,13 @@ scheme://username:password/smtpserver:port The options are: -| Part | Description | -|:-----------|:--------------------| +| Part | Description | +|:-----------|:--------------------------------------------------------------------------------------------------------| | scheme | The email scheme: smtp, ssl, tls, mandrill and ses. Note that mandrill and ses use your own private api | -| username | The username | -| password | The password | -| smtpserver | The SMTP Host | -| port | The SMTP Port | +| username | The username | +| password | The password | +| smtpserver | The SMTP Host | +| port | The SMTP Port | The protocols available are: @@ -205,7 +205,7 @@ class MyWrapper extends \ByJG\Mail\Wrapper\BaseWrapper return ['mywrapper']; } - public function send(Envelope $envelope) + public function send(Envelope $envelope): \ByJG\Mail\SendResult { // Do how to send the email using your library } diff --git a/src/SendResult.php b/src/SendResult.php new file mode 100644 index 0000000..3d0ba2f --- /dev/null +++ b/src/SendResult.php @@ -0,0 +1,11 @@ +validate($envelope); @@ -53,7 +54,7 @@ public function send(Envelope $envelope): bool $ses = $this->getSesClient(); - $ses->sendRawEmail( + $result = $ses->sendRawEmail( [ 'RawMessage' => [ 'Data' => $message, @@ -61,6 +62,6 @@ public function send(Envelope $envelope): bool ] ); - return true; + return new SendResult(true, $result->get('MessageId')); } } diff --git a/src/Wrapper/MailWrapperInterface.php b/src/Wrapper/MailWrapperInterface.php index 3803881..9648439 100644 --- a/src/Wrapper/MailWrapperInterface.php +++ b/src/Wrapper/MailWrapperInterface.php @@ -3,10 +3,11 @@ namespace ByJG\Mail\Wrapper; use ByJG\Mail\Envelope; +use ByJG\Mail\SendResult; interface MailWrapperInterface { public static function schema(): array; - public function send(Envelope $envelope): bool; + public function send(Envelope $envelope): SendResult; } diff --git a/src/Wrapper/MailgunApiWrapper.php b/src/Wrapper/MailgunApiWrapper.php index 8e87cd0..cdea6f2 100644 --- a/src/Wrapper/MailgunApiWrapper.php +++ b/src/Wrapper/MailgunApiWrapper.php @@ -5,6 +5,7 @@ use ByJG\Mail\Envelope; use ByJG\Mail\Exception\InvalidEMailException; use ByJG\Mail\Exception\MailApiException; +use ByJG\Mail\SendResult; use ByJG\WebRequest\Exception\MessageException; use ByJG\WebRequest\Exception\NetworkException; use ByJG\WebRequest\Exception\RequestException; @@ -62,15 +63,15 @@ public function getRequestObject(): RequestInterface * malgun://api:APIKEY@DOMAINNAME * * @param Envelope $envelope - * @return bool + * @return SendResult + * @throws ClientExceptionInterface * @throws InvalidEMailException * @throws MailApiException * @throws MessageException - * @throws RequestException * @throws NetworkException - * @throws ClientExceptionInterface + * @throws RequestException */ - public function send(Envelope $envelope): bool + public function send(Envelope $envelope): SendResult { $this->validate($envelope); @@ -118,7 +119,9 @@ public function send(Envelope $envelope): bool throw new MailApiException('Mailgun: ' . $resultJson['message']); } - return true; + $messageId = $resultJson['id']; + + return new SendResult(true, $messageId); } private function getApiUri() diff --git a/src/Wrapper/PHPMailerWrapper.php b/src/Wrapper/PHPMailerWrapper.php index cae884b..43072f1 100644 --- a/src/Wrapper/PHPMailerWrapper.php +++ b/src/Wrapper/PHPMailerWrapper.php @@ -6,6 +6,7 @@ use ByJG\Mail\Exception\InvalidEMailException; use ByJG\Mail\Exception\MailApiException; use ByJG\Mail\Override\PHPMailerOverride; +use ByJG\Mail\SendResult; use ByJG\Mail\Util; use InvalidArgumentException; use PHPMailer\PHPMailer\Exception; @@ -100,12 +101,12 @@ protected function prepareMailer(Envelope $envelope): PHPMailerOverride /** * @param Envelope $envelope - * @return bool - * @throws MailApiException - * @throws InvalidEMailException + * @return SendResult * @throws Exception + * @throws InvalidEMailException + * @throws MailApiException */ - public function send(Envelope $envelope): bool + public function send(Envelope $envelope): SendResult { $this->validate($envelope); @@ -124,6 +125,6 @@ public function send(Envelope $envelope): bool throw new MailApiException($mail->ErrorInfo); } - return true; + return new SendResult(true, $mail->getLastMessageID()); } } diff --git a/src/Wrapper/SendMailWrapper.php b/src/Wrapper/SendMailWrapper.php index c205f78..ac75ede 100644 --- a/src/Wrapper/SendMailWrapper.php +++ b/src/Wrapper/SendMailWrapper.php @@ -5,6 +5,7 @@ use ByJG\Mail\Envelope; use ByJG\Mail\Exception\InvalidEMailException; use ByJG\Mail\Exception\InvalidMessageFormatException; +use ByJG\Mail\SendResult; use PHPMailer\PHPMailer\Exception; /** @@ -24,12 +25,12 @@ public static function schema(): array /** * @param Envelope $envelope - * @return bool + * @return SendResult + * @throws Exception * @throws InvalidEMailException * @throws InvalidMessageFormatException - * @throws Exception */ - public function send(Envelope $envelope): bool + public function send(Envelope $envelope): SendResult { $this->validate($envelope); @@ -47,6 +48,6 @@ public function send(Envelope $envelope): bool mail($toEmail, $envelope->getSubject(), $messageParts['body'], $messageParts['header']); } - return true; + return new SendResult(true, $mail->getLastMessageID()); } } diff --git a/tests/AmazonSesWrapperTest.php b/tests/AmazonSesWrapperTest.php index ccdc504..e449c61 100644 --- a/tests/AmazonSesWrapperTest.php +++ b/tests/AmazonSesWrapperTest.php @@ -3,16 +3,23 @@ namespace Tests; use Aws\Credentials\Credentials; +use ByJG\Mail\Exception\InvalidEMailException; +use ByJG\Mail\Exception\InvalidMessageFormatException; +use ByJG\Mail\SendResult; use ByJG\Mail\Wrapper\AmazonSesWrapper; use ByJG\Util\Uri; +use PHPMailer\PHPMailer\Exception; class AmazonSesWrapperTest extends BaseWrapperTest { /** * @param $envelope - * @return MockSender + * @return array + * @throws InvalidEMailException + * @throws InvalidMessageFormatException + * @throws Exception */ - public function doMockedRequest($envelope) + public function doMockedRequest($envelope): array { $object = $this->getMockBuilder(AmazonSesWrapper::class) ->onlyMethods(['getSesClient']) @@ -24,9 +31,9 @@ public function doMockedRequest($envelope) ->method('getSesClient') ->will($this->returnValue($mock)); - $object->send($envelope); + $result = $object->send($envelope); - return $mock; + return [$mock, $result]; } public function testGetSesClient() @@ -46,9 +53,14 @@ public function testGetSesClient() $this->assertEquals('2010-12-01', $sesClient->getApi()->getApiVersion()); } - protected function send($envelope, $rawEmail) + /** + * @throws Exception + * @throws InvalidMessageFormatException + * @throws InvalidEMailException + */ + protected function send($envelope, $rawEmail): SendResult { - $mock = $this->doMockedRequest($envelope); + [$mock, $result] = $this->doMockedRequest($envelope); $mimeMessage = $this->fixVariableFields(file_get_contents(__DIR__ . '/resources/' . $rawEmail . '.eml')); $mock->result['RawMessage']['Data'] = $this->fixVariableFields($mock->result['RawMessage']['Data']); @@ -59,29 +71,63 @@ protected function send($envelope, $rawEmail) ]; $this->assertEquals($expected, $mock->result); + + return $result; } + /** + * @throws Exception + * @throws InvalidMessageFormatException + * @throws InvalidEMailException + */ public function testBasicEnvelope() { $envelope = $this->getBasicEnvelope(); - $this->send($envelope, 'basicenvelope'); + $result = $this->send($envelope, 'basicenvelope'); + + $this->assertTrue($result->success); + $this->assertEquals('EXAMPLEf3f73d99b-c63fb06f-d263-41f8-a0fb-d0dc67d56c07-000000', $result->id); } + /** + * @throws Exception + * @throws InvalidMessageFormatException + * @throws InvalidEMailException + */ public function testFullEnvelope() { $envelope = $this->getFullEnvelope(); - $this->send($envelope, 'fullenvelope'); + $result = $this->send($envelope, 'fullenvelope'); + + $this->assertTrue($result->success); + $this->assertEquals('EXAMPLEf3f73d99b-c63fb06f-d263-41f8-a0fb-d0dc67d56c07-000000', $result->id); } + /** + * @throws Exception + * @throws InvalidMessageFormatException + * @throws InvalidEMailException + */ public function testAttachmentEnvelope() { $envelope = $this->getAttachmentEnvelope(); - $this->send($envelope, 'attachmentenvelope'); + $result = $this->send($envelope, 'attachmentenvelope'); + + $this->assertTrue($result->success); + $this->assertEquals('EXAMPLEf3f73d99b-c63fb06f-d263-41f8-a0fb-d0dc67d56c07-000000', $result->id); } + /** + * @throws Exception + * @throws InvalidMessageFormatException + * @throws InvalidEMailException + */ public function testEmbedImageEnvelope() { $envelope = $this->getEmbedImageEnvelope(); - $this->send($envelope, 'embedenvelope'); + $result = $this->send($envelope, 'embedenvelope'); + + $this->assertTrue($result->success); + $this->assertEquals('EXAMPLEf3f73d99b-c63fb06f-d263-41f8-a0fb-d0dc67d56c07-000000', $result->id); } } diff --git a/tests/MailgunWrapperTest.php b/tests/MailgunWrapperTest.php index 17c8b50..9054140 100644 --- a/tests/MailgunWrapperTest.php +++ b/tests/MailgunWrapperTest.php @@ -5,6 +5,7 @@ use ByJG\Mail\Envelope; use ByJG\Mail\Exception\InvalidEMailException; use ByJG\Mail\Exception\MailApiException; +use ByJG\Mail\SendResult; use ByJG\Mail\Wrapper\MailgunApiWrapper; use ByJG\WebRequest\Exception\MessageException; use ByJG\WebRequest\Exception\NetworkException; @@ -21,20 +22,24 @@ class MailgunWrapperTest extends BaseWrapperTest /** * @param Envelope $envelope * @param MockClient $mock - * @return bool + * @return SendResult + * @throws ClientExceptionInterface * @throws InvalidEMailException * @throws MailApiException * @throws MessageException * @throws NetworkException * @throws RequestException - * @throws ClientExceptionInterface */ - public function doMockedRequest(Envelope $envelope, MockClient $mock): bool + public function doMockedRequest(Envelope $envelope, MockClient $mock): SendResult { $object = new MailgunApiWrapper(new Uri('mailgun://YOUR_API_KEY@YOUR_DOMAIN'), $mock); return $object->send($envelope); } + /** + * @throws RequestException + * @throws MessageException + */ public function testGetRequest() { $wrapper = new MailgunApiWrapper(new Uri('mailgun://YOUR_API_KEY@YOUR_DOMAIN')); @@ -43,6 +48,14 @@ public function testGetRequest() $this->assertEquals("api:YOUR_API_KEY", $request->getUri()->getUserInfo()); } + /** + * @throws MailApiException + * @throws RequestException + * @throws NetworkException + * @throws ClientExceptionInterface + * @throws InvalidEMailException + * @throws MessageException + */ public function testBasicEnvelope() { $expectedResponse = new Response(200); @@ -54,8 +67,19 @@ public function testBasicEnvelope() $result = $this->doMockedRequest($envelope, $mock); $expected = $this->fixRequestBody(file_get_contents(__DIR__ . "/resources/basicenvelope-request.txt")); $this->assertEquals($expected, $this->fixRequestBody($mock->getRequestedObject()->getBody()->getContents())); + + $this->assertTrue($result->success); + $this->assertEquals('12345', $result->id); } + /** + * @throws MailApiException + * @throws RequestException + * @throws NetworkException + * @throws InvalidEMailException + * @throws ClientExceptionInterface + * @throws MessageException + */ public function testFullEnvelope() { $expectedResponse = new Response(200); @@ -67,8 +91,19 @@ public function testFullEnvelope() $result = $this->doMockedRequest($envelope, $mock); $expected = $this->fixRequestBody(file_get_contents(__DIR__ . "/resources/fullenvelope-request.txt")); $this->assertEquals($expected, $this->fixRequestBody($mock->getRequestedObject()->getBody()->getContents())); + + $this->assertTrue($result->success); + $this->assertEquals('12345', $result->id); } + /** + * @throws MailApiException + * @throws RequestException + * @throws NetworkException + * @throws ClientExceptionInterface + * @throws InvalidEMailException + * @throws MessageException + */ public function testAttachmentEnvelope() { $expectedResponse = new Response(200); @@ -80,8 +115,19 @@ public function testAttachmentEnvelope() $result = $this->doMockedRequest($envelope, $mock); $expected = $this->fixRequestBody(file_get_contents(__DIR__ . "/resources/attachmentenvelope-request.txt")); $this->assertEquals($expected, $this->fixRequestBody($mock->getRequestedObject()->getBody()->getContents())); + + $this->assertTrue($result->success); + $this->assertEquals('12345', $result->id); } + /** + * @throws MailApiException + * @throws NetworkException + * @throws RequestException + * @throws InvalidEMailException + * @throws ClientExceptionInterface + * @throws MessageException + */ public function testEmbedImageEnvelope() { $expectedResponse = new Response(200); @@ -93,5 +139,8 @@ public function testEmbedImageEnvelope() $result = $this->doMockedRequest($envelope, $mock); $expected = $this->fixRequestBody(file_get_contents(__DIR__ . "/resources/embedenvelope-request.txt")); $this->assertEquals($expected, $this->fixRequestBody($mock->getRequestedObject()->getBody()->getContents())); + + $this->assertTrue($result->success); + $this->assertEquals('12345', $result->id); } } diff --git a/tests/MockSender.php b/tests/MockSender.php index 926b2a0..d361ca4 100644 --- a/tests/MockSender.php +++ b/tests/MockSender.php @@ -2,6 +2,8 @@ namespace Tests; +use Aws\Result; + class MockSender { public $result; @@ -10,6 +12,10 @@ class MockSender public function sendRawEmail($raw) { $this->result = $raw; + + return new Result([ + 'MessageId' => 'EXAMPLEf3f73d99b-c63fb06f-d263-41f8-a0fb-d0dc67d56c07-000000', + ]); } // Mailgun Wrapper diff --git a/tests/PHPMailerWrapperTest.php b/tests/PHPMailerWrapperTest.php index 7a05bed..d0c3e0a 100644 --- a/tests/PHPMailerWrapperTest.php +++ b/tests/PHPMailerWrapperTest.php @@ -13,21 +13,25 @@ class PHPMailerWrapperTest extends BaseWrapperTest { /** * @param $envelope - * @return PHPMailerOverride + * @return array + * @throws Exception * @throws InvalidEMailException * @throws MailApiException - * @throws Exception */ - public function doMockedRequest($envelope): PHPMailerOverride + public function doMockedRequest($envelope): array { $mock = $this->getMockBuilder(PHPMailerOverride::class) - ->onlyMethods(['send']) + ->onlyMethods(['send', 'getLastMessageID']) ->setConstructorArgs([true]) ->getMock(); + $mock->expects($this->once()) ->method('send') - ->will($this->returnValue(true)); + ->willReturn(true); + $mock->expects($this->once()) + ->method('getLastMessageID') + ->willReturn('mocked-message-id'); $object = $this->getMockBuilder(PHPMailerWrapper::class) ->onlyMethods(['getMailer']) @@ -36,20 +40,22 @@ public function doMockedRequest($envelope): PHPMailerOverride $object->expects($this->once()) ->method('getMailer') - ->will($this->returnValue($mock)); + ->willReturn($mock); - $object->send($envelope); + $sendResult = $object->send($envelope); - return $mock; + return [$mock, $sendResult]; } protected function send($envelope, $rawEmail) { - $mock = $this->doMockedRequest($envelope); + [$mock, $sendResult] = $this->doMockedRequest($envelope); $expected = $this->fixVariableFields(file_get_contents(__DIR__ . '/resources/' . $rawEmail . '.eml')); $result = $this->fixVariableFields($mock->getFullMessageEnvelope()); $this->assertEquals($expected, $result); + $this->assertTrue($sendResult->success); + $this->assertEquals('mocked-message-id', $sendResult->id); } public function testBasicEnvelope()