From de59213f2cd0f33471dd60b0e630ad1902894a03 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 22 Feb 2025 16:16:02 +0100 Subject: [PATCH 01/12] upgrade to phpunit 8.5 so tests can be run on modern PHP --- composer.json | 2 +- tests/MailerTest.php | 2 +- tests/OAuthTest.php | 2 +- tests/SMTPTest.php | 11 +++++++---- tests/TestCase.php | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index e3620d2..b71132f 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "psr/log": "~1.0" }, "require-dev": { - "phpunit/phpunit": "~5.0", + "phpunit/phpunit": "~8.5", "monolog/monolog": "~1.13" }, "autoload": { diff --git a/tests/MailerTest.php b/tests/MailerTest.php index 55f54e1..dbba376 100644 --- a/tests/MailerTest.php +++ b/tests/MailerTest.php @@ -9,7 +9,7 @@ class MailerTest extends TestCase { - public function setup() + public function setUp(): void { } diff --git a/tests/OAuthTest.php b/tests/OAuthTest.php index c9a55d5..fc80786 100644 --- a/tests/OAuthTest.php +++ b/tests/OAuthTest.php @@ -11,7 +11,7 @@ class OAuthTest extends TestCase public function testOAuth2() { if(!self::OAUTH_TOKEN){ - return; + $this->markTestSkipped('No oauth token set, test skipped'); } $mail = new Mailer(new Logger('Mailer.OAuth')); $status = $mail->setServer(self::OAUTH_SERVER, self::OAUTH_PORT, 'tls') diff --git a/tests/SMTPTest.php b/tests/SMTPTest.php index 1e885cd..93afa78 100644 --- a/tests/SMTPTest.php +++ b/tests/SMTPTest.php @@ -30,7 +30,7 @@ class SMTPTest extends TestCase */ protected $message; - public function setup() + public function setUp(): void { $this->message = new Message(); $this->message @@ -71,6 +71,11 @@ public function testTLSSend() public function testTLSv10Send() { + if (!defined('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT')) { + $this->markTestSkipped('TLS 1.0 not supported by PHP version'); + } + + $this->smtp = new SMTP(new Logger('SMTP.tlsv1.0')); $this->smtp ->setServer(self::SERVER, self::PORT_TLS, 'tlsv1.0') @@ -105,11 +110,9 @@ public function testTLSv12Send() usleep(self::DELAY); } - /** - * @expectedException \Tx\Mailer\Exceptions\SMTPException - */ public function testConnectSMTPException() { + $this->expectException(\Tx\Mailer\Exceptions\SMTPException::class); $this->smtp = new SMTP(new Logger('SMTP.FakePort')); $this->smtp ->setServer('localhost', "99999", null) diff --git a/tests/TestCase.php b/tests/TestCase.php index d3b2495..e4e529e 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -3,7 +3,7 @@ /** * Configures the SMTP server used for testing */ -class TestCase extends \PHPUnit_Framework_TestCase +class TestCase extends \PHPUnit\Framework\TestCase { /** SMTP server to test against */ const SERVER = 'smtp.mailtrap.io'; From 5d8f337714759fb9f1facb249d22b6b564ee2ddb Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 22 Feb 2025 16:16:55 +0100 Subject: [PATCH 02/12] don't use specific TLS versions anymore Modern PHP releases do not support old and insecure TLS versions anymore. In general it's not advised to let end users decide on the TLS version or hardcode those versions into the library, since these things change and you run the risk running an outdated version. For example the code did not support TLS1.3 before this patch, because only 1.2 was known at the time of writing the original code. This patch ignores the passed version and will always let PHP pick the recommended versions. --- src/Mailer/SMTP.php | 24 ++++-------------------- tests/SMTPTest.php | 41 ----------------------------------------- 2 files changed, 4 insertions(+), 61 deletions(-) diff --git a/src/Mailer/SMTP.php b/src/Mailer/SMTP.php index 9ed80ef..592f030 100644 --- a/src/Mailer/SMTP.php +++ b/src/Mailer/SMTP.php @@ -108,7 +108,8 @@ public function __construct(LoggerInterface $logger=null) * set server and port * @param string $host server * @param int $port port - * @param string $secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2 + * @param string $secure ssl tls + * @param bool $allowInsecure skip certificate verification? * @return $this */ public function setServer($host, $port, $secure=null, $allowInsecure=null) @@ -116,7 +117,7 @@ public function setServer($host, $port, $secure=null, $allowInsecure=null) $this->host = $host; $this->port = $port; $this->secure = $secure; - $this->allowInsecure = $allowInsecure; + $this->allowInsecure = (bool) $allowInsecure; if(!$this->ehlo) $this->ehlo = $host; $this->logger && $this->logger->debug("Set: the server"); return $this; @@ -254,24 +255,7 @@ protected function starttls() throw new CryptoException('Crypto type expected PHP 5.6 or greater'); } - switch ($this->secure) { - case 'tlsv1.0': - $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT; - break; - case 'tlsv1.1': - $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; - break; - case 'tlsv1.2': - $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; - break; - default: - $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | - STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | - STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; - break; - } - - if(!\stream_socket_enable_crypto($this->smtp, true, $crypto_type)) { + if(!\stream_socket_enable_crypto($this->smtp, true, STREAM_CRYPTO_METHOD_ANY_CLIENT)) { throw new CryptoException("Start TLS failed to enable crypto"); } return $this; diff --git a/tests/SMTPTest.php b/tests/SMTPTest.php index 93afa78..68c11b3 100644 --- a/tests/SMTPTest.php +++ b/tests/SMTPTest.php @@ -69,47 +69,6 @@ public function testTLSSend() usleep(self::DELAY); } - public function testTLSv10Send() - { - if (!defined('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT')) { - $this->markTestSkipped('TLS 1.0 not supported by PHP version'); - } - - - $this->smtp = new SMTP(new Logger('SMTP.tlsv1.0')); - $this->smtp - ->setServer(self::SERVER, self::PORT_TLS, 'tlsv1.0') - ->setAuth(self::USER, self::PASS); - - $status = $this->smtp->send($this->message); - $this->assertTrue($status); - usleep(self::DELAY); - } - - public function testTLSv11Send() - { - $this->smtp = new SMTP(new Logger('SMTP.tlsv1.1')); - $this->smtp - ->setServer(self::SERVER, self::PORT_TLS, 'tlsv1.1') - ->setAuth(self::USER, self::PASS); - - $status = $this->smtp->send($this->message); - $this->assertTrue($status); - usleep(self::DELAY); - } - - public function testTLSv12Send() - { - $this->smtp = new SMTP(new Logger('SMTP.tlsv1.2')); - $this->smtp - ->setServer(self::SERVER, self::PORT_TLS, 'tlsv1.2') - ->setAuth(self::USER, self::PASS); - - $status = $this->smtp->send($this->message); - $this->assertTrue($status); - usleep(self::DELAY); - } - public function testConnectSMTPException() { $this->expectException(\Tx\Mailer\Exceptions\SMTPException::class); From aa677d60d386bc7a55aa12e8f46fce5fdd72bfed Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 22 Feb 2025 16:32:16 +0100 Subject: [PATCH 03/12] use github actions instead of travis Travis seems to have been broken for a while anyway. --- .github/workflows/php-tests.yml | 30 ++++++++++++++++++++++++++++++ .gitignore | 1 + .travis.yml | 11 ----------- phpunit.xml.dist | 20 ++++++++++---------- 4 files changed, 41 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/php-tests.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/php-tests.yml b/.github/workflows/php-tests.yml new file mode 100644 index 0000000..7d3ae03 --- /dev/null +++ b/.github/workflows/php-tests.yml @@ -0,0 +1,30 @@ +name: PHP Tests + +on: + push: + pull_request: + +jobs: + test: + name: PHP ${{ matrix.php-versions }} + runs-on: ubuntu-latest + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + strategy: + matrix: + php-version: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] + fail-fast: false + + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + + - name: Install Dependencies + run: composer install + + - name: Run Tests + run: ./vendor/bin/phpunit --configuration phpunit.xml.dist --verbose diff --git a/.gitignore b/.gitignore index 96e828d..07cc02f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ composer.lock .idea/ docs/ phpunit.xml +.phpunit.result.cache diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b174b06..0000000 --- a/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: php -sudo: false -php: - - "7.4" - - "7.3" - - "7.2" - - "7.1" - - "7.0" - - "5.6" -install: composer update -script: ./vendor/bin/phpunit --verbose diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3732559..81b1c2f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ - - vendor - + + + vendor + + - + From 9b7d9f5921ae9667519cc0b1990bca581c7378b8 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 22 Feb 2025 16:33:12 +0100 Subject: [PATCH 04/12] minimum requirement is PHP 5.4 The code was using short array syntax already, this only makes the composer file reflect the code requirements. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b71132f..f8b41d4 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ } ], "require": { - "php": ">=5.3.2", + "php": ">=5.4", "psr/log": "~1.0" }, "require-dev": { From 470a2590bb420c98b33c405e6d7e851c70e3c676 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 22 Feb 2025 16:38:44 +0100 Subject: [PATCH 05/12] suppress errors while connecting There should not be an error thrown before our own Exception is thrown. --- src/Mailer/SMTP.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mailer/SMTP.php b/src/Mailer/SMTP.php index 592f030..0153d2c 100644 --- a/src/Mailer/SMTP.php +++ b/src/Mailer/SMTP.php @@ -215,7 +215,7 @@ protected function connect() ] ]); } - $this->smtp = stream_socket_client( + $this->smtp = @stream_socket_client( $host.':'.$this->port, $error_code, $error_message, From fa9b82d881f139771f5177e996e439004d359ece Mon Sep 17 00:00:00 2001 From: "Andreas Gohr (aider)" Date: Sat, 22 Feb 2025 16:44:36 +0100 Subject: [PATCH 06/12] test: Add comprehensive tests for Message class functionality --- tests/MessageTest.php | 91 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tests/MessageTest.php diff --git a/tests/MessageTest.php b/tests/MessageTest.php new file mode 100644 index 0000000..3ef6356 --- /dev/null +++ b/tests/MessageTest.php @@ -0,0 +1,91 @@ +message = new Message(); + } + + public function testSetFrom() + { + $this->message->setFrom('Sender Name', 'sender@example.com'); + $this->assertEquals('Sender Name', $this->message->getFromName()); + $this->assertEquals('sender@example.com', $this->message->getFromEmail()); + } + + public function testSetFakeFrom() + { + $this->message->setFakeFrom('Fake Name', 'fake@example.com'); + $this->assertEquals('Fake Name', $this->message->getFakeFromName()); + $this->assertEquals('fake@example.com', $this->message->getFakeFromEmail()); + } + + public function testAddTo() + { + $this->message->addTo('Recipient', 'recipient@example.com'); + $to = $this->message->getTo(); + $this->assertArrayHasKey('recipient@example.com', $to); + $this->assertEquals('Recipient', $to['recipient@example.com']); + } + + public function testAddCc() + { + $this->message->addCc('CC Recipient', 'cc@example.com'); + $cc = $this->message->getCc(); + $this->assertArrayHasKey('cc@example.com', $cc); + $this->assertEquals('CC Recipient', $cc['cc@example.com']); + } + + public function testAddBcc() + { + $this->message->addBcc('BCC Recipient', 'bcc@example.com'); + $bcc = $this->message->getBcc(); + $this->assertArrayHasKey('bcc@example.com', $bcc); + $this->assertEquals('BCC Recipient', $bcc['bcc@example.com']); + } + + public function testSetSubject() + { + $subject = 'Test Subject'; + $this->message->setSubject($subject); + $this->assertEquals($subject, $this->message->getSubject()); + } + + public function testSetBody() + { + $body = 'Test email body content'; + $this->message->setBody($body); + $this->assertEquals($body, $this->message->getBody()); + } + + public function testSetReplyTo() + { + $this->message->setReplyTo('Reply Name', 'reply@example.com'); + $messageString = $this->message->toString(); + $this->assertStringContainsString('Reply-To: =?utf-8?B?' . base64_encode('Reply Name') . '?= ', $messageString); + } + + public function testToString() + { + $this->message + ->setFrom('Sender', 'sender@example.com') + ->setSubject('Test Subject') + ->setBody('Test Body') + ->addTo('Recipient', 'recipient@example.com'); + + $messageString = $this->message->toString(); + + $this->assertStringContainsString('From: =?utf-8?B?' . base64_encode('Sender') . '?= ', $messageString); + $this->assertStringContainsString('To: =?utf-8?B?' . base64_encode('Recipient') . '?= ', $messageString); + $this->assertStringContainsString('Subject: =?utf-8?B?' . base64_encode('Test Subject') . '?=', $messageString); + $this->assertStringContainsString(chunk_split(base64_encode('Test Body')), $messageString); + } +} From 5e435e197d08638ff3c4ddd281ba10d2100a1a88 Mon Sep 17 00:00:00 2001 From: "Andreas Gohr (aider)" Date: Sat, 22 Feb 2025 16:49:26 +0100 Subject: [PATCH 07/12] Add message testing This is mostly autogenerated for now but should provide a good starting point for proper testing of the message class. --- tests/MessageTest.php | 176 +++++++++++++++++++++++++++++++++++------- 1 file changed, 147 insertions(+), 29 deletions(-) diff --git a/tests/MessageTest.php b/tests/MessageTest.php index 3ef6356..019fa52 100644 --- a/tests/MessageTest.php +++ b/tests/MessageTest.php @@ -2,6 +2,7 @@ namespace Tx\Tests; +use PHPUnit\Framework\TestCase; use Tx\Mailer\Message; class MessageTest extends TestCase @@ -10,82 +11,199 @@ class MessageTest extends TestCase protected function setUp(): void { - parent::setUp(); $this->message = new Message(); } public function testSetFrom() { - $this->message->setFrom('Sender Name', 'sender@example.com'); - $this->assertEquals('Sender Name', $this->message->getFromName()); - $this->assertEquals('sender@example.com', $this->message->getFromEmail()); + $name = 'Sender Name'; + $email = 'sender@example.com'; + $expectedHeader = 'From: =?utf-8?B?U2VuZGVyIE5hbWU=?= '; + + $this->message->setFrom($name, $email); + + // Test getters + $this->assertEquals($name, $this->message->getFromName()); + $this->assertEquals($email, $this->message->getFromEmail()); + + // Test toString output + $messageString = $this->message->toString(); + $this->assertStringContainsString($expectedHeader, $messageString); } public function testSetFakeFrom() { - $this->message->setFakeFrom('Fake Name', 'fake@example.com'); - $this->assertEquals('Fake Name', $this->message->getFakeFromName()); - $this->assertEquals('fake@example.com', $this->message->getFakeFromEmail()); + $name = 'Fake Name'; + $email = 'fake@example.com'; + $expectedHeader = 'From: =?utf-8?B?RmFrZSBOYW1l?= '; + + $this->message->setFakeFrom($name, $email); + + // Test getters + $this->assertEquals($name, $this->message->getFakeFromName()); + $this->assertEquals($email, $this->message->getFakeFromEmail()); + + // Test toString output + $messageString = $this->message->toString(); + $this->assertStringContainsString($expectedHeader, $messageString); } public function testAddTo() { - $this->message->addTo('Recipient', 'recipient@example.com'); + $name = 'Recipient'; + $email = 'recipient@example.com'; + $expectedHeader = 'To: =?utf-8?B?UmVjaXBpZW50?= '; + + $this->message->addTo($name, $email); + + // Test getter $to = $this->message->getTo(); - $this->assertArrayHasKey('recipient@example.com', $to); - $this->assertEquals('Recipient', $to['recipient@example.com']); + $this->assertArrayHasKey($email, $to); + $this->assertEquals($name, $to[$email]); + + // Test toString output + $messageString = $this->message->toString(); + $this->assertStringContainsString($expectedHeader, $messageString); } public function testAddCc() { - $this->message->addCc('CC Recipient', 'cc@example.com'); + $name = 'CC Recipient'; + $email = 'cc@example.com'; + $expectedHeader = 'Cc: =?utf-8?B?Q0MgUmVjaXBpZW50?= '; + + $this->message->addCc($name, $email); + + // Test getter $cc = $this->message->getCc(); - $this->assertArrayHasKey('cc@example.com', $cc); - $this->assertEquals('CC Recipient', $cc['cc@example.com']); + $this->assertArrayHasKey($email, $cc); + $this->assertEquals($name, $cc[$email]); + + // Test toString output + $messageString = $this->message->toString(); + $this->assertStringContainsString($expectedHeader, $messageString); } public function testAddBcc() { - $this->message->addBcc('BCC Recipient', 'bcc@example.com'); + $name = 'BCC Recipient'; + $email = 'bcc@example.com'; + $expectedHeader = 'Bcc: =?utf-8?B?QkNDIFJlY2lwaWVudA==?= '; + + $this->message->addBcc($name, $email); + + // Test getter $bcc = $this->message->getBcc(); - $this->assertArrayHasKey('bcc@example.com', $bcc); - $this->assertEquals('BCC Recipient', $bcc['bcc@example.com']); + $this->assertArrayHasKey($email, $bcc); + $this->assertEquals($name, $bcc[$email]); + + // Test toString output + $messageString = $this->message->toString(); + $this->assertStringContainsString($expectedHeader, $messageString); } public function testSetSubject() { - $subject = 'Test Subject'; + $subject = 'Test Subject with Special Chars: äöü'; + $this->message->setSubject($subject); + + // Test getter $this->assertEquals($subject, $this->message->getSubject()); + + // Test toString output + $messageString = $this->message->toString(); + $expectedHeader = 'Subject: =?utf-8?B?VGVzdCBTdWJqZWN0IHdpdGggU3BlY2lhbCBDaGFyczogw6TDtsO8?='; + $this->assertStringContainsString($expectedHeader, $messageString); } public function testSetBody() { - $body = 'Test email body content'; + $body = 'Test email body content with special chars: äöü'; + $this->message->setBody($body); + + // Test getter $this->assertEquals($body, $this->message->getBody()); + + // Test toString output + $messageString = $this->message->toString(); + $expectedBody = "VGVzdCBlbWFpbCBib2R5IGNvbnRlbnQgd2l0aCBzcGVjaWFsIGNoYXJzOiDDpMO2w7w=\r\n"; + $this->assertStringContainsString($expectedBody, $messageString); } public function testSetReplyTo() { - $this->message->setReplyTo('Reply Name', 'reply@example.com'); + $name = 'Reply Name'; + $email = 'reply@example.com'; + $expectedHeader = 'Reply-To: =?utf-8?B?UmVwbHkgTmFtZQ==?= '; + + $this->message->setReplyTo($name, $email); + + // Test toString output + $messageString = $this->message->toString(); + $this->assertStringContainsString($expectedHeader, $messageString); + } + + public function testAddAttachment() + { + $name = 'test.txt'; + $path = tempnam(sys_get_temp_dir(), 'test_'); + + + // Create a test file + file_put_contents($path, 'Test content'); + + $this->message->addAttachment($name, $path); + + // Test getter + $attachments = $this->message->getAttachment(); + $this->assertArrayHasKey($name, $attachments); + $this->assertEquals($path, $attachments[$name]); + + // Test toString output $messageString = $this->message->toString(); - $this->assertStringContainsString('Reply-To: =?utf-8?B?' . base64_encode('Reply Name') . '?= ', $messageString); + $this->assertStringContainsString( + 'Content-Type: application/octet-stream; name="' . $name . '"', + $messageString + ); + $this->assertStringContainsString( + 'Content-Disposition: attachment; filename="' . $name . '"', + $messageString + ); + + // Cleanup + unlink($path); } - public function testToString() + public function testCompleteMessage() { + $fromName = 'Sender'; + $fromEmail = 'sender@example.com'; + $toName = 'Recipient'; + $toEmail = 'recipient@example.com'; + $subject = 'Complete Test'; + $body = 'Complete test body'; + $expectedHeaderFrom = 'From: =?utf-8?B?U2VuZGVy?= '; + $expectedHeaderTo = 'To: =?utf-8?B?UmVjaXBpZW50?= '; + $expectedHeaderSubject = 'Subject: =?utf-8?B?Q29tcGxldGUgVGVzdA==?='; + $expectedBody = "Q29tcGxldGUgdGVzdCBib2R5\r\n"; + $this->message - ->setFrom('Sender', 'sender@example.com') - ->setSubject('Test Subject') - ->setBody('Test Body') - ->addTo('Recipient', 'recipient@example.com'); + ->setFrom($fromName, $fromEmail) + ->addTo($toName, $toEmail) + ->setSubject($subject) + ->setBody($body); $messageString = $this->message->toString(); - $this->assertStringContainsString('From: =?utf-8?B?' . base64_encode('Sender') . '?= ', $messageString); - $this->assertStringContainsString('To: =?utf-8?B?' . base64_encode('Recipient') . '?= ', $messageString); - $this->assertStringContainsString('Subject: =?utf-8?B?' . base64_encode('Test Subject') . '?=', $messageString); - $this->assertStringContainsString(chunk_split(base64_encode('Test Body')), $messageString); + // Verify all parts are present and properly encoded + + $this->assertStringContainsString($expectedHeaderFrom, $messageString); + $this->assertStringContainsString($expectedHeaderTo, $messageString); + $this->assertStringContainsString($expectedHeaderSubject, $messageString); + $this->assertStringContainsString($expectedBody, $messageString); + $this->assertStringContainsString('MIME-Version: 1.0', $messageString); + $this->assertStringContainsString('Content-Type: multipart/alternative', $messageString); } } From e68fac70ba6ee21731870d7df17388e35764c93f Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 22 Feb 2025 18:35:07 +0100 Subject: [PATCH 08/12] use namespace for tests --- composer.json | 6 +++--- tests/MailerTest.php | 15 +++++---------- tests/MessageTest.php | 5 ++--- tests/OAuthTest.php | 9 ++++----- tests/SMTPTest.php | 10 +++------- tests/TestCase.php | 6 +++++- 6 files changed, 22 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index f8b41d4..e9cc2e2 100644 --- a/composer.json +++ b/composer.json @@ -31,8 +31,8 @@ } }, "autoload-dev": { - "classmap": [ - "tests/TestCase.php" - ] + "psr-4": { + "Tx\\Mailer\\Tests\\": "tests/" + } } } diff --git a/tests/MailerTest.php b/tests/MailerTest.php index dbba376..bd5c3e3 100644 --- a/tests/MailerTest.php +++ b/tests/MailerTest.php @@ -1,18 +1,13 @@ addTo(self::TO_NAME, self::TO_EMAIL) ->addCc(self::CC_NAME, self::CC_EMAIL) ->addBcc(self::BCC_NAME, self::BCC_EMAIL) - ->setSubject('Test Mailer '. time()) + ->setSubject('Test Mailer ' . time()) ->setBody('Hi, boy') ->addAttachment('test', __FILE__) ->send(); diff --git a/tests/MessageTest.php b/tests/MessageTest.php index 019fa52..55df3c3 100644 --- a/tests/MessageTest.php +++ b/tests/MessageTest.php @@ -1,8 +1,7 @@ message->toString(); // Verify all parts are present and properly encoded - + $this->assertStringContainsString($expectedHeaderFrom, $messageString); $this->assertStringContainsString($expectedHeaderTo, $messageString); $this->assertStringContainsString($expectedHeaderSubject, $messageString); diff --git a/tests/OAuthTest.php b/tests/OAuthTest.php index fc80786..02472ae 100644 --- a/tests/OAuthTest.php +++ b/tests/OAuthTest.php @@ -1,10 +1,9 @@ Date: Sat, 22 Feb 2025 19:08:54 +0100 Subject: [PATCH 09/12] skip cert verification for TLS when requested #30 This should disable certificate validation when allowInsecure is set to true similar to when SSL connections are used. This is currently untested. --- src/Mailer/SMTP.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Mailer/SMTP.php b/src/Mailer/SMTP.php index 0153d2c..1c5512b 100644 --- a/src/Mailer/SMTP.php +++ b/src/Mailer/SMTP.php @@ -255,6 +255,12 @@ protected function starttls() throw new CryptoException('Crypto type expected PHP 5.6 or greater'); } + if ($this->allowInsecure) { + stream_context_set_option($this->smtp, 'ssl', 'verify_peer', false); + stream_context_set_option($this->smtp, 'ssl', 'verify_peer_name', false); + stream_context_set_option($this->smtp, 'ssl', 'allow_self_signed', true); + } + if(!\stream_socket_enable_crypto($this->smtp, true, STREAM_CRYPTO_METHOD_ANY_CLIENT)) { throw new CryptoException("Start TLS failed to enable crypto"); } From ff326205080cb468f167e4ab56e931d9c68070be Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 22 Feb 2025 19:25:40 +0100 Subject: [PATCH 10/12] run only 1 test in paralell when running test on github actions, we can not run multiple tests at the same time or we will run into the mailtrap request limits. --- .github/workflows/php-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/php-tests.yml b/.github/workflows/php-tests.yml index 7d3ae03..f81ee59 100644 --- a/.github/workflows/php-tests.yml +++ b/.github/workflows/php-tests.yml @@ -14,6 +14,7 @@ jobs: matrix: php-version: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] fail-fast: false + max-parallel: 1 steps: - uses: actions/checkout@v4 From e2b84c3558a1787e71bc32caa69a9588640bed94 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 22 Feb 2025 19:28:49 +0100 Subject: [PATCH 11/12] fix typo in test names, fail fast --- .github/workflows/php-tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/php-tests.yml b/.github/workflows/php-tests.yml index f81ee59..0a3df8a 100644 --- a/.github/workflows/php-tests.yml +++ b/.github/workflows/php-tests.yml @@ -6,14 +6,13 @@ on: jobs: test: - name: PHP ${{ matrix.php-versions }} + name: PHP ${{ matrix.php-version }} runs-on: ubuntu-latest if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository strategy: matrix: php-version: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] - fail-fast: false max-parallel: 1 steps: From bdcfcdd8381ea0b311c251906511193c1169c6cc Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 25 Feb 2025 13:59:41 +0100 Subject: [PATCH 12/12] fix socket opening on older php versions On older php versions you may not pass a null context to stream_socket_client(). This path creates a empty standard context instead. The exception message has been extended to give more detail about the failed connection. The commented stream blocking code has been removed. The connection is opened in blocking mode by default. --- src/Mailer/SMTP.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Mailer/SMTP.php b/src/Mailer/SMTP.php index 1c5512b..50bc3c1 100644 --- a/src/Mailer/SMTP.php +++ b/src/Mailer/SMTP.php @@ -205,7 +205,7 @@ protected function connect() $this->logger && $this->logger->debug("Connecting to {$this->host} at {$this->port}"); $host = ($this->secure == 'ssl') ? 'ssl://' . $this->host : $this->host; // Create connection - $context = null; + $context = stream_context_create([]); if ($this->allowInsecure) { $context = stream_context_create([ 'ssl' => [ @@ -223,10 +223,8 @@ protected function connect() STREAM_CLIENT_CONNECT, $context ); - //set block mode - // stream_set_blocking($this->smtp, 1); if (!$this->smtp){ - throw new SMTPException("Could not open SMTP Port."); + throw new SMTPException("Could not open SMTP Port to $host:{$this->port}"); } $code = $this->getCode(); if ($code !== '220'){