diff --git a/.circleci/config.yml b/.circleci/config.yml index 847e337b..62770a37 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,14 +5,9 @@ version: 2.1 workflows: php-tests: jobs: - - unit-tests: - name: php81 - version: "8.1" - unit-tests: name: php82 version: "8.2" - requires: - - php81 - unit-tests: name: php83 version: "8.3" @@ -23,6 +18,11 @@ workflows: version: "8.4" requires: - php83 + - unit-tests: + name: php85 + version: "8.5" + requires: + - php84 jobs: unit-tests: diff --git a/composer.json b/composer.json index 6a3cd734..88872815 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "license": "MIT", "description": "The officially supported client for Postmark (https://postmarkapp.com)", "require": { - "php": "~8.1 || ~8.2|| ~8.3 || ~8.4", + "php": "~8.2|| ~8.3 || ~8.4 || ~8.5", "guzzlehttp/guzzle": "^7.8" }, "require-dev": { diff --git a/src/Postmark/Models/PostmarkAttachment.php b/src/Postmark/Models/PostmarkAttachment.php index 4d2ddf03..90a8368f 100644 --- a/src/Postmark/Models/PostmarkAttachment.php +++ b/src/Postmark/Models/PostmarkAttachment.php @@ -20,17 +20,17 @@ private function __construct($base64EncodedData, $attachmentName, $mimeType = 'a $this->contentId = $contentId; } - public static function fromRawData($data, $attachmentName, ?string $mimeType = null, ?string $contentId = null) + public static function fromRawData(string $data, string $attachmentName, ?string $mimeType = null, ?string $contentId = null): PostmarkAttachment { return new PostmarkAttachment(base64_encode($data), $attachmentName, $mimeType, $contentId); } - public static function fromBase64EncodedData($base64EncodedData, $attachmentName, ?string $mimeType = null, ?string $contentId = null) + public static function fromBase64EncodedData(string $base64EncodedData, string $attachmentName, ?string $mimeType = null, ?string $contentId = null): PostmarkAttachment { return new PostmarkAttachment($base64EncodedData, $attachmentName, $mimeType, $contentId); } - public static function fromFile($filePath, $attachmentName, ?string $mimeType = null, ?string $contentId = null) + public static function fromFile(string $filePath, string $attachmentName, ?string $mimeType = null, ?string $contentId = null): PostmarkAttachment { return new PostmarkAttachment(base64_encode(file_get_contents($filePath)), $attachmentName, $mimeType, $contentId); } diff --git a/src/Postmark/Models/PostmarkBounceList.php b/src/Postmark/Models/PostmarkBounceList.php index b2393b15..7a005b4c 100644 --- a/src/Postmark/Models/PostmarkBounceList.php +++ b/src/Postmark/Models/PostmarkBounceList.php @@ -11,7 +11,8 @@ public function __construct(array $values) { $this->TotalCount = !empty($values['TotalCount']) ? $values['TotalCount'] : 0; $tempBounce = []; - foreach ($values['Bounces'] as $bounce) { + $bounces = $values['Bounces'] ?? []; + foreach ($bounces as $bounce) { $obj = json_decode(json_encode($bounce)); $postmarkBounce = new PostmarkBounce((array) $obj); diff --git a/src/Postmark/Models/PostmarkInboundMessageList.php b/src/Postmark/Models/PostmarkInboundMessageList.php index 27c39ed4..056c9a01 100644 --- a/src/Postmark/Models/PostmarkInboundMessageList.php +++ b/src/Postmark/Models/PostmarkInboundMessageList.php @@ -11,7 +11,8 @@ public function __construct(array $values) { $this->TotalCount = !empty($values['TotalCount']) ? $values['TotalCount'] : 0; $tempInboundMessages = []; - foreach ($values['InboundMessages'] as $message) { + $inboundMessages = $values['InboundMessages'] ?? []; + foreach ($inboundMessages as $message) { $obj = json_decode(json_encode($message)); $postmarkMessage = new PostmarkInboundMessage((array) $obj); diff --git a/src/Postmark/Models/PostmarkOpen.php b/src/Postmark/Models/PostmarkOpen.php index 53c7dc8f..3fe61e0a 100644 --- a/src/Postmark/Models/PostmarkOpen.php +++ b/src/Postmark/Models/PostmarkOpen.php @@ -63,7 +63,7 @@ public function setUserAgent(string $UserAgent): PostmarkOpen return $this; } - public function getGeo(): PostmarkGeographyInfo + public function getGeo(): ?PostmarkGeographyInfo { return $this->Geo; } @@ -114,7 +114,7 @@ public function setReceivedAt(string $ReceivedAt): PostmarkOpen return $this; } - public function getClient(): PostmarkAgentInfo + public function getClient(): ?PostmarkAgentInfo { return $this->Client; } @@ -129,7 +129,7 @@ public function setClient(mixed $Client): PostmarkOpen return $this; } - public function getOS(): PostmarkAgentInfo + public function getOS(): ?PostmarkAgentInfo { return $this->OS; } diff --git a/src/Postmark/Models/PostmarkOutboundMessageList.php b/src/Postmark/Models/PostmarkOutboundMessageList.php index 4bb63ff3..71ba7822 100644 --- a/src/Postmark/Models/PostmarkOutboundMessageList.php +++ b/src/Postmark/Models/PostmarkOutboundMessageList.php @@ -11,7 +11,8 @@ public function __construct(array $values) { $this->TotalCount = !empty($values['TotalCount']) ? $values['TotalCount'] : 0; $tempMessages = []; - foreach ($values['Messages'] as $message) { + $messages = $values['Messages'] ?? []; + foreach ($messages as $message) { $obj = json_decode(json_encode($message)); $postmarkMessage = new PostmarkOutboundMessage((array) $obj); diff --git a/src/Postmark/Models/Suppressions/PostmarkSuppressionList.php b/src/Postmark/Models/Suppressions/PostmarkSuppressionList.php index 193a79d7..7f4ef4f3 100644 --- a/src/Postmark/Models/Suppressions/PostmarkSuppressionList.php +++ b/src/Postmark/Models/Suppressions/PostmarkSuppressionList.php @@ -9,7 +9,8 @@ class PostmarkSuppressionList public function __construct(array $values) { $tempSuppressions = []; - foreach ($values['Suppressions'] as $sups) { + $suppressions = $values['Suppressions'] ?? []; + foreach ($suppressions as $sups) { $obj = json_decode(json_encode($sups)); $postmarkSup = new PostmarkSuppression((array) $obj); diff --git a/src/Postmark/Models/Suppressions/PostmarkSuppressionResultList.php b/src/Postmark/Models/Suppressions/PostmarkSuppressionResultList.php index c2d77c36..87551569 100644 --- a/src/Postmark/Models/Suppressions/PostmarkSuppressionResultList.php +++ b/src/Postmark/Models/Suppressions/PostmarkSuppressionResultList.php @@ -9,7 +9,8 @@ class PostmarkSuppressionResultList public function __construct(array $values) { $tempSuppressions = []; - foreach ($values['Suppressions'] as $sups) { + $suppressions = $values['Suppressions'] ?? []; + foreach ($suppressions as $sups) { $obj = json_decode(json_encode($sups)); $postmarkSup = new PostmarkSuppressionRequestResult((array) $obj); diff --git a/src/Postmark/PostmarkClient.php b/src/Postmark/PostmarkClient.php index 912d68ff..d579a057 100644 --- a/src/Postmark/PostmarkClient.php +++ b/src/Postmark/PostmarkClient.php @@ -306,7 +306,7 @@ public function getDeliveryStatistics(): PostmarkDeliveryStats * @param null|bool $inactive specifies if the bounce caused Postmark to deactivate this email * @param null|string $emailFilter Filter by email address * @param null|string $tag Filter by tag - * @param null|int $messageID Filter by MessageID + * @param null|string $messageID Filter by MessageID * @param null|string $fromdate filter for bounces after is date * @param null|string $todate filter for bounces before this date * @param null|string $messagestream Filter by Message Stream ID. If null, the default "outbound" transactional stream will be used. @@ -320,7 +320,7 @@ public function getBounces( ?bool $inactive = null, ?string $emailFilter = null, ?string $tag = null, - ?int $messageID = null, + ?string $messageID = null, ?string $fromdate = null, ?string $todate = null, ?string $messagestream = null diff --git a/tests/PostmarkClientBounceTest.php b/tests/PostmarkClientBounceTest.php index d98fa0fc..cab198b1 100644 --- a/tests/PostmarkClientBounceTest.php +++ b/tests/PostmarkClientBounceTest.php @@ -18,6 +18,48 @@ public static function setUpBeforeClass(): void PostmarkClientSuppressionsTest::tearDownAfterClass(); } + /** + * @depends testClientCanActivateBounce + */ + public function testClientCanGetBounce() + { + $tk = parent::$testKeys; + $client = new PostmarkClient($tk->READ_SELENIUM_TEST_SERVER_TOKEN, $tk->TEST_TIMEOUT); + $bounces = $client->getBounces(10, 0); + $bounceList = $bounces->getBounces(); + + if (empty($bounceList)) { + $this->markTestSkipped('No bounces available for testing'); + return; + } + + $id = $bounceList[0]->getID(); + $bounce = $client->getBounce($id); + $this->assertNotEmpty($bounce); + $this->assertEquals($id, $bounce->getID()); + } + + /** + * @depends testClientCanActivateBounce + */ + public function testClientCanGetBounceDump() + { + $tk = parent::$testKeys; + $client = new PostmarkClient($tk->READ_SELENIUM_TEST_SERVER_TOKEN, $tk->TEST_TIMEOUT); + $bounces = $client->getBounces(10, 0); + $bounceList = $bounces->getBounces(); + + if (empty($bounceList)) { + $this->markTestSkipped('No bounces available for testing'); + return; + } + + $id = $bounceList[0]->getID(); + $dump = $client->getBounceDump($id); + $this->assertNotEmpty($dump); + $this->assertNotEmpty($dump->getBody()); + } + public function testClientCanActivateBounce() { $tk = parent::$testKeys; @@ -105,32 +147,5 @@ public function testClientCanGetBounces() $bounces = $client->getBounces(10, 0); $this->assertNotEmpty($bounces); } - - /** - * @depends testClientCanActivateBounce - */ - public function testClientCanGetBounce() - { - $tk = parent::$testKeys; - $client = new PostmarkClient($tk->READ_SELENIUM_TEST_SERVER_TOKEN, $tk->TEST_TIMEOUT); - $bounces = $client->getBounces(10, 0); - $id = $bounces->getBounces()[0]->getID(); - $bounce = $client->getBounce($id); - $this->assertNotEmpty($bounce); - $this->assertEquals($id, $bounce->getID()); - } - - /** - * @depends testClientCanActivateBounce - */ - public function testClientCanGetBounceDump() - { - $tk = parent::$testKeys; - $client = new PostmarkClient($tk->READ_SELENIUM_TEST_SERVER_TOKEN, $tk->TEST_TIMEOUT); - $bounces = $client->getBounces(10, 0); - $id = $bounces->Bounces[0]->getID(); - $dump = $client->getBounceDump($id); - $this->assertNotEmpty($dump); - $this->assertNotEmpty($dump->getBody()); - } + } diff --git a/tests/PostmarkClientInboundMessageTest.php b/tests/PostmarkClientInboundMessageTest.php index da8f8405..50283863 100644 --- a/tests/PostmarkClientInboundMessageTest.php +++ b/tests/PostmarkClientInboundMessageTest.php @@ -30,7 +30,14 @@ public function testClientCanGetInboundMessageDetails() $client = new PostmarkClient($tk->READ_SELENIUM_TEST_SERVER_TOKEN, $tk->TEST_TIMEOUT); $retrievedMessages = $client->getInboundMessages(10); - $baseMessageId = $retrievedMessages->getInboundMessages()[0]->getMessageID(); + $inboundMessages = $retrievedMessages->getInboundMessages(); + + if (empty($inboundMessages)) { + $this->markTestSkipped('No inbound messages available for testing'); + return; + } + + $baseMessageId = $inboundMessages[0]->getMessageID(); $message = $client->getInboundMessageDetails($baseMessageId); $this->assertNotEmpty($message); diff --git a/tests/PostmarkClientOutboundMessageTest.php b/tests/PostmarkClientOutboundMessageTest.php index d35cee68..78c39ede 100644 --- a/tests/PostmarkClientOutboundMessageTest.php +++ b/tests/PostmarkClientOutboundMessageTest.php @@ -29,8 +29,14 @@ public function testClientCanGetOutboundMessageDetails() $client = new PostmarkClient($tk->READ_SELENIUM_TEST_SERVER_TOKEN, $tk->TEST_TIMEOUT); $retrievedMessages = $client->getOutboundMessages(1, 50); - - $baseMessageId = $retrievedMessages->getMessages()[0]->getMessageID(); + $messages = $retrievedMessages->getMessages(); + + if (empty($messages)) { + $this->markTestSkipped('No outbound messages available for testing'); + return; + } + + $baseMessageId = $messages[0]->getMessageID(); $message = $client->getOutboundMessageDetails($baseMessageId); $this->assertNotEmpty($message); @@ -42,7 +48,14 @@ public function testClientCanGetOutboundMessageDump() $client = new PostmarkClient($tk->READ_SELENIUM_TEST_SERVER_TOKEN, $tk->TEST_TIMEOUT); $retrievedMessages = $client->getOutboundMessages(1, 50); - $baseMessageId = $retrievedMessages->getMessages()[0]->getMessageID(); + $messages = $retrievedMessages->getMessages(); + + if (empty($messages)) { + $this->markTestSkipped('No outbound messages available for testing'); + return; + } + + $baseMessageId = $messages[0]->getMessageID(); $message = $client->getOutboundMessageDump($baseMessageId); $this->assertNotEmpty($message); diff --git a/tests/PostmarkClientSuppressionsTest.php b/tests/PostmarkClientSuppressionsTest.php index 894b1032..a08ad588 100644 --- a/tests/PostmarkClientSuppressionsTest.php +++ b/tests/PostmarkClientSuppressionsTest.php @@ -21,11 +21,18 @@ public static function tearDownAfterClass(): void $client = new PostmarkClient($tk->WRITE_TEST_SERVER_TOKEN, $tk->TEST_TIMEOUT); // remove all suppressions on the default stream - $sups = $client->getSuppressions(); - foreach ($sups->getSuppressions() as $sup) { - $suppressionChanges = [new SuppressionChangeRequest($sup->getEmailAddress())]; - $messageStream = 'outbound'; - $client->deleteSuppressions($suppressionChanges, $messageStream); + try { + $sups = $client->getSuppressions(); + $suppressions = $sups->getSuppressions(); + if (!empty($suppressions)) { + foreach ($suppressions as $sup) { + $suppressionChanges = [new SuppressionChangeRequest($sup->getEmailAddress())]; + $messageStream = 'outbound'; + $client->deleteSuppressions($suppressionChanges, $messageStream); + } + } + } catch (PostmarkException $e) { + // Ignore errors during cleanup } }