From df3f462eb286a8b61ca36c55d29e2b6b240a4c42 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 15 May 2024 12:29:56 +0200 Subject: [PATCH 01/23] remove the old php version (7.4) --- .github/workflows/ci-phpunit.yml | 4 +--- .github/workflows/ci-psalm.yaml | 2 +- composer.json | 13 +++++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-phpunit.yml b/.github/workflows/ci-phpunit.yml index 40fe4ce..aa8d875 100644 --- a/.github/workflows/ci-phpunit.yml +++ b/.github/workflows/ci-phpunit.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: [ ubuntu-latest ] - php-version: [ '7.4','8.0','8.1','8.2','8.3' ] + php-version: [ '8.0','8.1','8.2','8.3' ] steps: - name: Checkout @@ -58,8 +58,6 @@ jobs: strategy: matrix: include: - - symfony: '5' - php-version: '7.4' - symfony: '6' php-version: '8.2' - symfony: '7' diff --git a/.github/workflows/ci-psalm.yaml b/.github/workflows/ci-psalm.yaml index ffa9464..e3faa58 100644 --- a/.github/workflows/ci-psalm.yaml +++ b/.github/workflows/ci-psalm.yaml @@ -15,7 +15,7 @@ jobs: strategy: matrix: os: [ ubuntu-latest ] - php-versions: [ '7.4','8.0','8.1','8.2','8.3' ] + php-versions: [ '8.0','8.1','8.2','8.3' ] steps: - name: Checkout diff --git a/composer.json b/composer.json index ba47a62..fb3298f 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "homepage": "https://github.com/railsware/mailtrap-php", "license": "MIT", "require": { - "php": "^7.4 || ^8.0", + "php": "^8.0", "ext-curl": "*", "ext-json": "*", "psr/http-message": "^1.0 || ^2.0", @@ -14,15 +14,16 @@ "php-http/httplug": "^2.0", "php-http/discovery": "^1.0", "php-http/message-factory": "^1.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "egulias/email-validator": "^2.1.10|^3.1|^4" + "symfony/mime": "^6.0|^7.0", + "egulias/email-validator": "^3|^4" }, "require-dev": { - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/mailer": "^5.4|^6.0|^7.0", + "symfony/http-client": "^6.0|^7.0", + "symfony/mailer": "^6.0|^7.0", "phpunit/phpunit": "^9", "nyholm/psr7": "^1.5", - "vimeo/psalm": "^4.0 || ^5.0" + "vimeo/psalm": "^5.0", + "rector/rector": "dev-main" }, "suggest": { "nyholm/psr7": "PSR-7 message implementation", From f056939ce43d0cf5c57034cb7c3875fd3102adb4 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 15 May 2024 12:37:27 +0200 Subject: [PATCH 02/23] fix addr-spec in tests (RFC 2822) --- tests/Api/AbstractEmailsTest.php | 28 ++++++++++++++-------------- tests/Api/Sandbox/EmailsTest.php | 8 ++++---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/Api/AbstractEmailsTest.php b/tests/Api/AbstractEmailsTest.php index 507f3c2..b3ceaaa 100644 --- a/tests/Api/AbstractEmailsTest.php +++ b/tests/Api/AbstractEmailsTest.php @@ -41,7 +41,7 @@ public function testValidSend(): void ]; $email = new Email(); - $email->from(new Address('foo@example.com', 'Ms. Foo Bar')) + $email->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) ->replyTo(new Address('reply@example.com')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ->priority(Email::PRIORITY_HIGH) @@ -59,7 +59,7 @@ public function testValidSend(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'foo@example.com', + 'email' => 'from.adress.email@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -105,7 +105,7 @@ public function testInValidSend(): void ); $email = new Email(); - $email->from(new Address('foo@example.com', 'Ms. Foo Bar')) + $email->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) ->text('Some text') ->html('

Some text

') ; @@ -117,7 +117,7 @@ public function testInValidSend(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'foo@example.com', + 'email' => 'from.adress.email@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [], @@ -142,7 +142,7 @@ public function testValidSendTemplate(): void ]; $email = (new Email()) - ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ; @@ -160,7 +160,7 @@ public function testValidSendTemplate(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'foo@example.com', + 'email' => 'from.adress.email@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -190,7 +190,7 @@ public function testValidSendTemplate(): void public function testAttachments(): void { $email = (new Email()) - ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) ->attach('fake_body', 'fakeFile.jpg', 'image/jpg') ; @@ -212,7 +212,7 @@ public function testAttachments(): void */ public function testHeaders($name, $value): void { - $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); $email->getHeaders()->addTextHeader($name, $value); $method = new \ReflectionMethod(Emails::class, 'getPayload'); @@ -229,7 +229,7 @@ public function testHeaders($name, $value): void */ public function testCustomVariables($name, $value): void { - $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CustomVariableHeader($name, $value)); @@ -247,7 +247,7 @@ public function testCustomVariables($name, $value): void */ public function testEmailCategory($value): void { - $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CategoryHeader($value)); @@ -261,7 +261,7 @@ public function testEmailCategory($value): void public function testInvalidCountOfEmailCategory(): void { - $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CategoryHeader('category 1')) ->add(new CategoryHeader('category 2')) @@ -283,7 +283,7 @@ public function testInvalidCountOfEmailCategory(): void */ public function testTemplateUuid($value): void { - $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateUuidHeader($value)); @@ -297,7 +297,7 @@ public function testTemplateUuid($value): void public function testInvalidCountOfTemplateUuid(): void { - $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateUuidHeader('11111111-0000-0000-0000-8493da283a69')) ->add(new TemplateUuidHeader('22222222-0000-0000-0000-8493da283a69')) @@ -319,7 +319,7 @@ public function testInvalidCountOfTemplateUuid(): void */ public function testTemplateVariables($name, $value): void { - $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateVariableHeader($name, $value)); diff --git a/tests/Api/Sandbox/EmailsTest.php b/tests/Api/Sandbox/EmailsTest.php index 0b87bd7..a516997 100644 --- a/tests/Api/Sandbox/EmailsTest.php +++ b/tests/Api/Sandbox/EmailsTest.php @@ -55,7 +55,7 @@ public function testValidSendToSandBox(): void ]; $email = new Email(); - $email->from(new Address('foo@example.com', 'Ms. Foo Bar')) + $email->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) ->replyTo(new Address('reply@example.com')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ->priority(Email::PRIORITY_HIGH) @@ -72,7 +72,7 @@ public function testValidSendToSandBox(): void ->method('httpPost') ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . $inboxId, [], [ 'from' => [ - 'email' => 'foo@example.com', + 'email' => 'from.adress.email@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -113,7 +113,7 @@ public function testValidSendTemplateToSandbox(): void ]; $email = (new Email()) - ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ; @@ -131,7 +131,7 @@ public function testValidSendTemplateToSandbox(): void ->method('httpPost') ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . $inboxId, [], [ 'from' => [ - 'email' => 'foo@example.com', + 'email' => 'from.adress.email@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ From b6aff381d0b9d9b16c0d73b256f3b27e6fb0fbf3 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 15 May 2024 12:54:43 +0200 Subject: [PATCH 03/23] fix validator library version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index fb3298f..a815a2c 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php-http/discovery": "^1.0", "php-http/message-factory": "^1.0", "symfony/mime": "^6.0|^7.0", - "egulias/email-validator": "^3|^4" + "egulias/email-validator": "^3.1|^4" }, "require-dev": { "symfony/http-client": "^6.0|^7.0", From dcccbf35963bdf83eb04eed98ea1efbc6481a3c5 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 15 May 2024 12:57:35 +0200 Subject: [PATCH 04/23] change email in tests --- tests/Api/AbstractEmailsTest.php | 28 ++++++++++++++-------------- tests/Api/Sandbox/EmailsTest.php | 8 ++++---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/Api/AbstractEmailsTest.php b/tests/Api/AbstractEmailsTest.php index b3ceaaa..b41e6b8 100644 --- a/tests/Api/AbstractEmailsTest.php +++ b/tests/Api/AbstractEmailsTest.php @@ -41,7 +41,7 @@ public function testValidSend(): void ]; $email = new Email(); - $email->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) + $email->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) ->replyTo(new Address('reply@example.com')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ->priority(Email::PRIORITY_HIGH) @@ -59,7 +59,7 @@ public function testValidSend(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'from.adress.email@example.com', + 'email' => 'phpnuit@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -105,7 +105,7 @@ public function testInValidSend(): void ); $email = new Email(); - $email->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) + $email->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) ->text('Some text') ->html('

Some text

') ; @@ -117,7 +117,7 @@ public function testInValidSend(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'from.adress.email@example.com', + 'email' => 'phpnuit@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [], @@ -142,7 +142,7 @@ public function testValidSendTemplate(): void ]; $email = (new Email()) - ->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) + ->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ; @@ -160,7 +160,7 @@ public function testValidSendTemplate(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'from.adress.email@example.com', + 'email' => 'phpnuit@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -190,7 +190,7 @@ public function testValidSendTemplate(): void public function testAttachments(): void { $email = (new Email()) - ->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) + ->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) ->attach('fake_body', 'fakeFile.jpg', 'image/jpg') ; @@ -212,7 +212,7 @@ public function testAttachments(): void */ public function testHeaders($name, $value): void { - $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); $email->getHeaders()->addTextHeader($name, $value); $method = new \ReflectionMethod(Emails::class, 'getPayload'); @@ -229,7 +229,7 @@ public function testHeaders($name, $value): void */ public function testCustomVariables($name, $value): void { - $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CustomVariableHeader($name, $value)); @@ -247,7 +247,7 @@ public function testCustomVariables($name, $value): void */ public function testEmailCategory($value): void { - $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CategoryHeader($value)); @@ -261,7 +261,7 @@ public function testEmailCategory($value): void public function testInvalidCountOfEmailCategory(): void { - $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CategoryHeader('category 1')) ->add(new CategoryHeader('category 2')) @@ -283,7 +283,7 @@ public function testInvalidCountOfEmailCategory(): void */ public function testTemplateUuid($value): void { - $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateUuidHeader($value)); @@ -297,7 +297,7 @@ public function testTemplateUuid($value): void public function testInvalidCountOfTemplateUuid(): void { - $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateUuidHeader('11111111-0000-0000-0000-8493da283a69')) ->add(new TemplateUuidHeader('22222222-0000-0000-0000-8493da283a69')) @@ -319,7 +319,7 @@ public function testInvalidCountOfTemplateUuid(): void */ public function testTemplateVariables($name, $value): void { - $email = (new Email())->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateVariableHeader($name, $value)); diff --git a/tests/Api/Sandbox/EmailsTest.php b/tests/Api/Sandbox/EmailsTest.php index a516997..8ebf043 100644 --- a/tests/Api/Sandbox/EmailsTest.php +++ b/tests/Api/Sandbox/EmailsTest.php @@ -55,7 +55,7 @@ public function testValidSendToSandBox(): void ]; $email = new Email(); - $email->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) + $email->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) ->replyTo(new Address('reply@example.com')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ->priority(Email::PRIORITY_HIGH) @@ -72,7 +72,7 @@ public function testValidSendToSandBox(): void ->method('httpPost') ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . $inboxId, [], [ 'from' => [ - 'email' => 'from.adress.email@example.com', + 'email' => 'phpnuit@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -113,7 +113,7 @@ public function testValidSendTemplateToSandbox(): void ]; $email = (new Email()) - ->from(new Address('from.adress.email@example.com', 'Ms. Foo Bar')) + ->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ; @@ -131,7 +131,7 @@ public function testValidSendTemplateToSandbox(): void ->method('httpPost') ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . $inboxId, [], [ 'from' => [ - 'email' => 'from.adress.email@example.com', + 'email' => 'phpnuit@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ From 56843e36184d2e4e153962791e912cb256994b25 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 15 May 2024 13:09:20 +0200 Subject: [PATCH 05/23] check library dep (email validator) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a815a2c..914b9f0 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php-http/discovery": "^1.0", "php-http/message-factory": "^1.0", "symfony/mime": "^6.0|^7.0", - "egulias/email-validator": "^3.1|^4" + "egulias/email-validator": "^2.1.10|^3.1|^4" }, "require-dev": { "symfony/http-client": "^6.0|^7.0", From 0657254c8dc3b33ff6d303de38a9732b8a42a991 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 15 May 2024 13:14:38 +0200 Subject: [PATCH 06/23] revert email name in tests --- tests/Api/AbstractEmailsTest.php | 28 ++++++++++++++-------------- tests/Api/Sandbox/EmailsTest.php | 8 ++++---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/Api/AbstractEmailsTest.php b/tests/Api/AbstractEmailsTest.php index b41e6b8..507f3c2 100644 --- a/tests/Api/AbstractEmailsTest.php +++ b/tests/Api/AbstractEmailsTest.php @@ -41,7 +41,7 @@ public function testValidSend(): void ]; $email = new Email(); - $email->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) + $email->from(new Address('foo@example.com', 'Ms. Foo Bar')) ->replyTo(new Address('reply@example.com')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ->priority(Email::PRIORITY_HIGH) @@ -59,7 +59,7 @@ public function testValidSend(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'phpnuit@example.com', + 'email' => 'foo@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -105,7 +105,7 @@ public function testInValidSend(): void ); $email = new Email(); - $email->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) + $email->from(new Address('foo@example.com', 'Ms. Foo Bar')) ->text('Some text') ->html('

Some text

') ; @@ -117,7 +117,7 @@ public function testInValidSend(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'phpnuit@example.com', + 'email' => 'foo@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [], @@ -142,7 +142,7 @@ public function testValidSendTemplate(): void ]; $email = (new Email()) - ->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ; @@ -160,7 +160,7 @@ public function testValidSendTemplate(): void ->method('httpPost') ->with($this->getHost() . '/api/send', [], [ 'from' => [ - 'email' => 'phpnuit@example.com', + 'email' => 'foo@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -190,7 +190,7 @@ public function testValidSendTemplate(): void public function testAttachments(): void { $email = (new Email()) - ->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) ->attach('fake_body', 'fakeFile.jpg', 'image/jpg') ; @@ -212,7 +212,7 @@ public function testAttachments(): void */ public function testHeaders($name, $value): void { - $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); $email->getHeaders()->addTextHeader($name, $value); $method = new \ReflectionMethod(Emails::class, 'getPayload'); @@ -229,7 +229,7 @@ public function testHeaders($name, $value): void */ public function testCustomVariables($name, $value): void { - $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CustomVariableHeader($name, $value)); @@ -247,7 +247,7 @@ public function testCustomVariables($name, $value): void */ public function testEmailCategory($value): void { - $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CategoryHeader($value)); @@ -261,7 +261,7 @@ public function testEmailCategory($value): void public function testInvalidCountOfEmailCategory(): void { - $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new CategoryHeader('category 1')) ->add(new CategoryHeader('category 2')) @@ -283,7 +283,7 @@ public function testInvalidCountOfEmailCategory(): void */ public function testTemplateUuid($value): void { - $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateUuidHeader($value)); @@ -297,7 +297,7 @@ public function testTemplateUuid($value): void public function testInvalidCountOfTemplateUuid(): void { - $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateUuidHeader('11111111-0000-0000-0000-8493da283a69')) ->add(new TemplateUuidHeader('22222222-0000-0000-0000-8493da283a69')) @@ -319,7 +319,7 @@ public function testInvalidCountOfTemplateUuid(): void */ public function testTemplateVariables($name, $value): void { - $email = (new Email())->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')); + $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); $email->getHeaders() ->add(new TemplateVariableHeader($name, $value)); diff --git a/tests/Api/Sandbox/EmailsTest.php b/tests/Api/Sandbox/EmailsTest.php index 8ebf043..0b87bd7 100644 --- a/tests/Api/Sandbox/EmailsTest.php +++ b/tests/Api/Sandbox/EmailsTest.php @@ -55,7 +55,7 @@ public function testValidSendToSandBox(): void ]; $email = new Email(); - $email->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) + $email->from(new Address('foo@example.com', 'Ms. Foo Bar')) ->replyTo(new Address('reply@example.com')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ->priority(Email::PRIORITY_HIGH) @@ -72,7 +72,7 @@ public function testValidSendToSandBox(): void ->method('httpPost') ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . $inboxId, [], [ 'from' => [ - 'email' => 'phpnuit@example.com', + 'email' => 'foo@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ @@ -113,7 +113,7 @@ public function testValidSendTemplateToSandbox(): void ]; $email = (new Email()) - ->from(new Address('phpnuit@example.com', 'Ms. Foo Bar')) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) ->to(new Address('bar@example.com', 'Mr. Recipient')) ; @@ -131,7 +131,7 @@ public function testValidSendTemplateToSandbox(): void ->method('httpPost') ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . $inboxId, [], [ 'from' => [ - 'email' => 'phpnuit@example.com', + 'email' => 'foo@example.com', 'name' => 'Ms. Foo Bar', ], 'to' => [[ From eead16efdb976dba85f48b61c0c48c847e22a118 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 15 May 2024 14:44:42 +0200 Subject: [PATCH 07/23] improve code to PHP 8.0 --- composer.json | 3 +-- src/AbstractMailtrapClient.php | 8 ++------ src/Api/AbstractApi.php | 2 +- src/Api/Sandbox/Project.php | 2 +- src/Bridge/Transport/MailtrapApiTransport.php | 13 ++----------- src/Config.php | 4 +--- src/DTO/Request/Inbox.php | 7 +------ .../Request/Permission/CreateOrUpdatePermission.php | 6 +++--- src/DTO/Request/Permission/DestroyPermission.php | 4 ++-- src/Exception/HttpClientException.php | 6 +++--- src/Helper/ResponseHelper.php | 2 +- src/HttpClient/HttpClientBuilder.php | 4 +--- src/MailtrapBulkSendingClient.php | 2 -- src/MailtrapGeneralClient.php | 2 -- src/MailtrapSandboxClient.php | 2 -- src/MailtrapSendingClient.php | 2 -- tests/Api/General/UserTest.php | 2 +- tests/Bridge/Transport/TransportFactoryTestCase.php | 8 ++++---- tests/MailtrapTestCase.php | 1 - 19 files changed, 24 insertions(+), 56 deletions(-) diff --git a/composer.json b/composer.json index 914b9f0..42192a0 100644 --- a/composer.json +++ b/composer.json @@ -22,8 +22,7 @@ "symfony/mailer": "^6.0|^7.0", "phpunit/phpunit": "^9", "nyholm/psr7": "^1.5", - "vimeo/psalm": "^5.0", - "rector/rector": "dev-main" + "vimeo/psalm": "^5.0" }, "suggest": { "nyholm/psr7": "PSR-7 message implementation", diff --git a/src/AbstractMailtrapClient.php b/src/AbstractMailtrapClient.php index deef102..e395a00 100644 --- a/src/AbstractMailtrapClient.php +++ b/src/AbstractMailtrapClient.php @@ -4,7 +4,6 @@ namespace Mailtrap; -use Mailtrap\Api\AbstractApi; use Mailtrap\Exception\BadMethodCallException; use Mailtrap\Exception\InvalidArgumentException; @@ -13,18 +12,15 @@ */ abstract class AbstractMailtrapClient implements MailtrapClientInterface { - protected ConfigInterface $config; - - public function __construct(ConfigInterface $config) + public function __construct(protected ConfigInterface $config) { - $this->config = $config; } public function __call(string $name, array $arguments) { try { return $this->initByName($name); - } catch (InvalidArgumentException $e) { + } catch (InvalidArgumentException) { throw new BadMethodCallException(sprintf('%s -> undefined method called: "%s"', static::class, $name)); } } diff --git a/src/Api/AbstractApi.php b/src/Api/AbstractApi.php index 3768f8e..98842aa 100644 --- a/src/Api/AbstractApi.php +++ b/src/Api/AbstractApi.php @@ -117,7 +117,7 @@ protected function handleResponse(ResponseInterface $response): ResponseInterfac * * @return string */ - private function jsonEncode($value, int $flags = null, int $maxDepth = 512): string + private function jsonEncode(mixed $value, int $flags = null, int $maxDepth = 512): string { $flags ??= \JSON_HEX_TAG | \JSON_HEX_APOS | \JSON_HEX_AMP | \JSON_HEX_QUOT | \JSON_PRESERVE_ZERO_FRACTION; diff --git a/src/Api/Sandbox/Project.php b/src/Api/Sandbox/Project.php index 74869d7..ff5052a 100644 --- a/src/Api/Sandbox/Project.php +++ b/src/Api/Sandbox/Project.php @@ -42,7 +42,7 @@ public function getById(int $accountId, int $projectId): ResponseInterface } /** - * Create project + * Create a project * * @param int $accountId * @param string $projectName diff --git a/src/Bridge/Transport/MailtrapApiTransport.php b/src/Bridge/Transport/MailtrapApiTransport.php index dd9de30..c5fb457 100644 --- a/src/Bridge/Transport/MailtrapApiTransport.php +++ b/src/Bridge/Transport/MailtrapApiTransport.php @@ -23,22 +23,13 @@ */ class MailtrapApiTransport extends AbstractTransport { - /** - * @var MailtrapSendingClient|MailtrapSandboxClient - */ - private MailtrapClientInterface $mailtrapClient; - private ?int $inboxId; - public function __construct( - MailtrapClientInterface $mailtrapClient, - int $inboxId = null, + private MailtrapClientInterface $mailtrapClient, + private ?int $inboxId = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null ) { parent::__construct($dispatcher, $logger); - - $this->mailtrapClient = $mailtrapClient; - $this->inboxId = $inboxId; } public function __toString(): string diff --git a/src/Config.php b/src/Config.php index 7e7b029..757ede2 100644 --- a/src/Config.php +++ b/src/Config.php @@ -15,7 +15,6 @@ */ class Config implements ConfigInterface { - private string $apiToken; private ?ClientInterface $httpClient = null; private ?HttpClientBuilderInterface $httpClientBuilder = null; private ?RequestFactoryInterface $requestFactory = null; @@ -23,9 +22,8 @@ class Config implements ConfigInterface private ?string $host = null; private bool $responseThrowOnError = true; - public function __construct(string $apiToken) + public function __construct(private string $apiToken) { - $this->apiToken = $apiToken; } public function getApiToken(): string diff --git a/src/DTO/Request/Inbox.php b/src/DTO/Request/Inbox.php index 1c4917d..80e1e86 100644 --- a/src/DTO/Request/Inbox.php +++ b/src/DTO/Request/Inbox.php @@ -7,13 +7,8 @@ */ class Inbox implements RequestInterface { - private ?string $name; - private ?string $emailUsername; - - public function __construct(string $name = null, string $emailUsername = null) + public function __construct(private ?string $name = null, private ?string $emailUsername = null) { - $this->name = $name; - $this->emailUsername = $emailUsername; } /** diff --git a/src/DTO/Request/Permission/CreateOrUpdatePermission.php b/src/DTO/Request/Permission/CreateOrUpdatePermission.php index 89f9bcd..cfc7765 100644 --- a/src/DTO/Request/Permission/CreateOrUpdatePermission.php +++ b/src/DTO/Request/Permission/CreateOrUpdatePermission.php @@ -14,11 +14,11 @@ final class CreateOrUpdatePermission implements PermissionInterface private string $accessLevel; /** - * @param string|int $resourceId + * @param int|string $resourceId * @param string $resourceType - * @param string|int $accessLevel + * @param int|string $accessLevel */ - public function __construct($resourceId, string $resourceType, $accessLevel) + public function __construct(int|string $resourceId, string $resourceType, int|string $accessLevel) { $this->resourceId = (string) $resourceId; $this->resourceType = $resourceType; diff --git a/src/DTO/Request/Permission/DestroyPermission.php b/src/DTO/Request/Permission/DestroyPermission.php index b992a5c..c25ff1e 100644 --- a/src/DTO/Request/Permission/DestroyPermission.php +++ b/src/DTO/Request/Permission/DestroyPermission.php @@ -13,10 +13,10 @@ final class DestroyPermission implements PermissionInterface private string $resourceType; /** - * @param string|int $resourceId + * @param int|string $resourceId * @param string $resourceType */ - public function __construct($resourceId, string $resourceType) + public function __construct(int|string $resourceId, string $resourceType) { $this->resourceId = (string) $resourceId; $this->resourceType = $resourceType; diff --git a/src/Exception/HttpClientException.php b/src/Exception/HttpClientException.php index 5b9c2e1..c98f0a3 100644 --- a/src/Exception/HttpClientException.php +++ b/src/Exception/HttpClientException.php @@ -27,7 +27,7 @@ public static function createFromResponse(ResponseInterface $response): HttpClie try { $body = ResponseHelper::toArray($response); - } catch (JsonException|InvalidTypeException $e) { + } catch (JsonException|InvalidTypeException) { $body['error'] = $response->getBody()->__toString(); } @@ -56,11 +56,11 @@ public static function createFromResponse(ResponseInterface $response): HttpClie * {"errors": {"name":["is too short (minimum is 2 characters)"]}} 422 errorS (array with key name) * * - * @param string|array $errors + * @param array|string $errors * * @return string */ - public static function getErrorMsg($errors): string + public static function getErrorMsg(array|string $errors): string { $errorMsg = ''; if (is_array($errors)) { diff --git a/src/Helper/ResponseHelper.php b/src/Helper/ResponseHelper.php index 8092cd1..71b3dab 100644 --- a/src/Helper/ResponseHelper.php +++ b/src/Helper/ResponseHelper.php @@ -18,7 +18,7 @@ final class ResponseHelper */ public static function toArray(ResponseInterface $response): array { - if (strpos($response->getHeaderLine('Content-Type'), 'application/json') === false) { + if (!str_contains($response->getHeaderLine('Content-Type'), 'application/json')) { // This can happen when the URL structure changes and the response returns a 404 HTML page. (rare case) throw new InvalidTypeException(sprintf( 'Invalid content type in response. "%s" type expected, but received "%s"', diff --git a/src/HttpClient/HttpClientBuilder.php b/src/HttpClient/HttpClientBuilder.php index 0fbeffb..7538a4b 100644 --- a/src/HttpClient/HttpClientBuilder.php +++ b/src/HttpClient/HttpClientBuilder.php @@ -24,15 +24,13 @@ class HttpClientBuilder implements HttpClientBuilderInterface private RequestFactoryInterface $requestFactory; private StreamFactoryInterface $streamFactory; private ?HttpMethodsClientInterface $pluginClient = null; - private string $apiToken; public function __construct( - string $apiToken, + private string $apiToken, ClientInterface $httpClient = null, RequestFactoryInterface $requestFactory = null, StreamFactoryInterface $streamFactory = null ) { - $this->apiToken = $apiToken; $this->httpClient = $httpClient ?? Psr18ClientDiscovery::find(); $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory(); $this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory(); diff --git a/src/MailtrapBulkSendingClient.php b/src/MailtrapBulkSendingClient.php index f2ea025..4527848 100644 --- a/src/MailtrapBulkSendingClient.php +++ b/src/MailtrapBulkSendingClient.php @@ -4,8 +4,6 @@ namespace Mailtrap; -use Mailtrap\Api; - /** * @method Api\BulkSending\Emails emails * diff --git a/src/MailtrapGeneralClient.php b/src/MailtrapGeneralClient.php index 4460a60..4ec7906 100644 --- a/src/MailtrapGeneralClient.php +++ b/src/MailtrapGeneralClient.php @@ -4,8 +4,6 @@ namespace Mailtrap; -use Mailtrap\Api; - /** * @method Api\General\Account accounts * @method Api\General\User users diff --git a/src/MailtrapSandboxClient.php b/src/MailtrapSandboxClient.php index 3b0785d..fbdfbe7 100644 --- a/src/MailtrapSandboxClient.php +++ b/src/MailtrapSandboxClient.php @@ -4,8 +4,6 @@ namespace Mailtrap; -use Mailtrap\Api; - /** * @method Api\Sandbox\Emails emails * @method Api\Sandbox\Project projects diff --git a/src/MailtrapSendingClient.php b/src/MailtrapSendingClient.php index 8de9b73..d53d6e1 100644 --- a/src/MailtrapSendingClient.php +++ b/src/MailtrapSendingClient.php @@ -4,8 +4,6 @@ namespace Mailtrap; -use Mailtrap\Api; - /** * @method Api\Sending\Emails emails * diff --git a/tests/Api/General/UserTest.php b/tests/Api/General/UserTest.php index 915b0ec..bdf5f83 100644 --- a/tests/Api/General/UserTest.php +++ b/tests/Api/General/UserTest.php @@ -109,7 +109,7 @@ public function test403InvalidGetList(): void $this->user->getList(self::FAKE_ACCOUNT_ID); } - public function testValidRemove() + public function testValidRemove(): void { $this->user->expects($this->once()) ->method('httpDelete') diff --git a/tests/Bridge/Transport/TransportFactoryTestCase.php b/tests/Bridge/Transport/TransportFactoryTestCase.php index ddd1527..0d04f1e 100644 --- a/tests/Bridge/Transport/TransportFactoryTestCase.php +++ b/tests/Bridge/Transport/TransportFactoryTestCase.php @@ -43,7 +43,7 @@ public function incompleteDsnProvider(): iterable /** * @dataProvider supportsProvider */ - public function testSupports(Dsn $dsn, bool $supports) + public function testSupports(Dsn $dsn, bool $supports): void { $factory = $this->getFactory(); @@ -53,7 +53,7 @@ public function testSupports(Dsn $dsn, bool $supports) /** * @dataProvider createProvider */ - public function testCreate(Dsn $dsn, TransportInterface $transport) + public function testCreate(Dsn $dsn, TransportInterface $transport): void { $factory = $this->getFactory(); @@ -66,7 +66,7 @@ public function testCreate(Dsn $dsn, TransportInterface $transport) /** * @dataProvider unsupportedSchemeProvider */ - public function testUnsupportedSchemeException(Dsn $dsn, string $message = null) + public function testUnsupportedSchemeException(Dsn $dsn, string $message = null): void { $factory = $this->getFactory(); @@ -81,7 +81,7 @@ public function testUnsupportedSchemeException(Dsn $dsn, string $message = null) /** * @dataProvider incompleteDsnProvider */ - public function testIncompleteDsnException(Dsn $dsn) + public function testIncompleteDsnException(Dsn $dsn): void { $factory = $this->getFactory(); diff --git a/tests/MailtrapTestCase.php b/tests/MailtrapTestCase.php index a95c705..8878191 100644 --- a/tests/MailtrapTestCase.php +++ b/tests/MailtrapTestCase.php @@ -6,7 +6,6 @@ use Mailtrap\ConfigInterface; use Mailtrap\HttpClient\HttpClientBuilderInterface; -use Mailtrap\MailtrapClientInterface; use PHPUnit\Framework\TestCase; use Psr\Http\Client\ClientInterface; From 665bec5a2364f971312f4c6b7d257d5840e032f9 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Tue, 21 May 2024 14:36:22 +0200 Subject: [PATCH 08/23] implement inbox ID at the client level (emails) + tests --- .gitignore | 2 +- src/AbstractMailtrapClient.php | 6 +- src/Api/AbstractEmails.php | 2 +- src/Api/BulkSending/BulkSendingInterface.php | 2 + src/Api/EmailsSendApiInterface.php | 14 +++++ src/Api/General/GeneralInterface.php | 2 + src/Api/Sandbox/Attachment.php | 2 + src/Api/Sandbox/Emails.php | 15 ++++- src/Api/Sandbox/Inbox.php | 2 + src/Api/Sandbox/SandboxInterface.php | 2 + src/Api/Sending/SendingInterface.php | 2 + src/Bridge/Transport/MailtrapApiTransport.php | 21 ++++--- .../Transport/MailtrapTransportFactory.php | 54 ++++++++++++----- src/ConfigInterface.php | 2 + src/DTO/Request/Inbox.php | 2 + .../Permission/PermissionInterface.php | 2 + src/DTO/Request/RequestInterface.php | 2 + src/EmailsSendMailtrapClientInterface.php | 9 +++ .../Transport/UnsupportedHostException.php | 14 +++++ src/HttpClient/HttpClientBuilderInterface.php | 2 + src/MailtrapBulkSendingClient.php | 4 +- src/MailtrapSandboxClient.php | 4 +- src/MailtrapSendingClient.php | 4 +- tests/Api/Sandbox/EmailsTest.php | 12 ++-- .../Transport/MailtrapApiTransportTest.php | 28 ++++++--- .../MailtrapTransportFactoryTest.php | 59 ++++++++----------- .../Transport/TransportFactoryTestCase.php | 8 ++- tests/MailtrapSandboxClientTest.php | 7 ++- 28 files changed, 194 insertions(+), 91 deletions(-) create mode 100644 src/Api/EmailsSendApiInterface.php create mode 100644 src/EmailsSendMailtrapClientInterface.php create mode 100644 src/Exception/Transport/UnsupportedHostException.php diff --git a/.gitignore b/.gitignore index 98b110a..0ba965c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ phpunit.xml ###> files for local testing ### test.php docker-compose.yaml -Dockerfile +Dockerfile* ###> files for local testing ### ###> other ### diff --git a/src/AbstractMailtrapClient.php b/src/AbstractMailtrapClient.php index e395a00..84bc046 100644 --- a/src/AbstractMailtrapClient.php +++ b/src/AbstractMailtrapClient.php @@ -19,7 +19,7 @@ public function __construct(protected ConfigInterface $config) public function __call(string $name, array $arguments) { try { - return $this->initByName($name); + return $this->initByName($name, $arguments); } catch (InvalidArgumentException) { throw new BadMethodCallException(sprintf('%s -> undefined method called: "%s"', static::class, $name)); } @@ -36,7 +36,7 @@ private function getClassByName(string $name): ?string return !empty(static::API_MAPPING[$name]) ? static::API_MAPPING[$name] : null; } - private function initByName(string $name) + private function initByName(string $name, $arguments) { $className = $this->getClassByName($name); if (null === $className) { @@ -44,6 +44,6 @@ private function initByName(string $name) } /** @psalm-suppress LessSpecificReturnStatement */ - return new $className($this->getConfig()); + return new $className($this->getConfig(), ...$arguments); } } diff --git a/src/Api/AbstractEmails.php b/src/Api/AbstractEmails.php index 06c2b22..6c8f452 100644 --- a/src/Api/AbstractEmails.php +++ b/src/Api/AbstractEmails.php @@ -17,7 +17,7 @@ /** * Class AbstractEmails */ -abstract class AbstractEmails extends AbstractApi +abstract class AbstractEmails extends AbstractApi implements EmailsSendApiInterface { protected function getPayload(Email $email): array { diff --git a/src/Api/BulkSending/BulkSendingInterface.php b/src/Api/BulkSending/BulkSendingInterface.php index 51a5df1..98f0ffe 100644 --- a/src/Api/BulkSending/BulkSendingInterface.php +++ b/src/Api/BulkSending/BulkSendingInterface.php @@ -1,5 +1,7 @@ handleResponse( - $this->httpPost(sprintf('%s/api/send/%s', $this->getHost(), $inboxId), [], $this->getPayload($email)) + $this->httpPost(sprintf('%s/api/send/%s', $this->getHost(), $this->getInboxId()), [], $this->getPayload($email)) ); } @@ -24,4 +30,9 @@ protected function getHost(): string { return $this->config->getHost() ?: self::SENDMAIL_SANDBOX_HOST; } + + public function getInboxId(): int + { + return $this->inboxId; + } } diff --git a/src/Api/Sandbox/Inbox.php b/src/Api/Sandbox/Inbox.php index a85ff20..aeeb003 100644 --- a/src/Api/Sandbox/Inbox.php +++ b/src/Api/Sandbox/Inbox.php @@ -1,5 +1,7 @@ mailtrapClient->emails()->send($email, $this->inboxId); + $response = $this->emailsSendApiLayer->send($email); $body = ResponseHelper::toArray($response); $message->setMessageId(implode(',', $body['message_ids'])); } catch (\Exception $e) { throw new RuntimeException( - sprintf('Unable to send message with the "%s" transport: ', __CLASS__) . $e->getMessage(), 0, $e + sprintf('Unable to send a message with the "%s" transport: ', __CLASS__) . $e->getMessage(), 0, $e ); } } private function getEndpoint(): string { - return $this->mailtrapClient->getConfig()->getHost() . (null === $this->inboxId ? '' : '?inboxId=' . $this->inboxId); + $inboxId = null; + if ($this->emailsSendApiLayer instanceof SandboxEmails) { + $inboxId = $this->emailsSendApiLayer->getInboxId(); + } + + return $this->config->getHost() . (null === $inboxId ? '' : '?inboxId=' . $inboxId); } private function getEnvelopeRecipients(Email $email, Envelope $envelope): array diff --git a/src/Bridge/Transport/MailtrapTransportFactory.php b/src/Bridge/Transport/MailtrapTransportFactory.php index 1c970b2..10a5e29 100644 --- a/src/Bridge/Transport/MailtrapTransportFactory.php +++ b/src/Bridge/Transport/MailtrapTransportFactory.php @@ -6,7 +6,9 @@ use Mailtrap\Api\AbstractApi; use Mailtrap\Config; +use Mailtrap\EmailsSendMailtrapClientInterface; use Mailtrap\Exception\RuntimeException; +use Mailtrap\Exception\Transport\UnsupportedHostException; use Mailtrap\MailtrapClient; use Mailtrap\MailtrapClientInterface; use Mailtrap\MailtrapSandboxClient; @@ -33,14 +35,20 @@ public function create(Dsn $dsn): TransportInterface ->setHttpClient(null === $this->client ? null : new Psr18Client($this->client)) ; - $mailtrapClient = $this->getMailtrapClient($config); - if ($mailtrapClient instanceof MailtrapSandboxClient && null === $inboxId) { - throw new RuntimeException( - 'You cannot send email to the sandbox with empty "inboxId" param. Example -> "MAILER_DSN=mailtrap+api://APIKEY@sandbox.api.mailtrap.io?inboxId=1234"' - ); + $emailsSendMailtrapClient = $this->getEmailsSendMailTrapClient($config); + if ($emailsSendMailtrapClient instanceof MailtrapSandboxClient) { + if (null === $inboxId) { + throw new RuntimeException( + 'You cannot send an email to a sandbox with an empty "inboxId" parameter. Example -> "MAILER_DSN=mailtrap+api://APIKEY@sandbox.api.mailtrap.io?inboxId=1234"' + ); + } + + $emailsSendApiLayer = $emailsSendMailtrapClient->emails($inboxId); + } else { + $emailsSendApiLayer = $emailsSendMailtrapClient->emails(); } - return new MailtrapApiTransport($mailtrapClient, $inboxId, $this->dispatcher, $this->logger); + return new MailtrapApiTransport($emailsSendApiLayer, $config, $this->dispatcher, $this->logger); } protected function getSupportedSchemes(): array @@ -48,23 +56,39 @@ protected function getSupportedSchemes(): array return ['mailtrap', 'mailtrap+api']; } - private function getMailtrapClient(Config $config): MailtrapClientInterface + private function getEmailsSendMailTrapClient(Config $config): EmailsSendMailtrapClientInterface { - $layer = $this->determineLayerByHost($config->getHost()); + $layer = $this->determineLayerNameByHost($config->getHost()); return (new MailtrapClient($config))->{$layer}(); } - private function determineLayerByHost(string $host): string + private function determineLayerNameByHost(string $host): string { - if (stripos($host, AbstractApi::SENDMAIL_TRANSACTIONAL_HOST) !== false) { - return MailtrapClient::LAYER_TRANSACTIONAL_SENDING; - } + $hostLayers = [ + AbstractApi::SENDMAIL_TRANSACTIONAL_HOST => MailtrapClient::LAYER_TRANSACTIONAL_SENDING, + AbstractApi::SENDMAIL_BULK_HOST => MailtrapClient::LAYER_BULK_SENDING, + AbstractApi::SENDMAIL_SANDBOX_HOST => MailtrapClient::LAYER_SANDBOX, + ]; - if (stripos($host, AbstractApi::SENDMAIL_BULK_HOST) !== false) { - return MailtrapClient::LAYER_BULK_SENDING; + foreach ($hostLayers as $hostKey => $layer) { + if (stripos($host, $hostKey) !== false) { + return $layer; + } } - return MailtrapClient::LAYER_SANDBOX; + throw new UnsupportedHostException( + sprintf( + 'The "%s" host is not supported. Only these are available: %s', + $host, + implode( + ', ', + [ + AbstractApi::SENDMAIL_TRANSACTIONAL_HOST, + AbstractApi::SENDMAIL_BULK_HOST, + AbstractApi::SENDMAIL_SANDBOX_HOST + ] + )) + ); } } diff --git a/src/ConfigInterface.php b/src/ConfigInterface.php index b3caae6..a3c6313 100644 --- a/src/ConfigInterface.php +++ b/src/ConfigInterface.php @@ -1,5 +1,7 @@ Api\BulkSending\Emails::class, diff --git a/src/MailtrapSandboxClient.php b/src/MailtrapSandboxClient.php index fbdfbe7..c4114a2 100644 --- a/src/MailtrapSandboxClient.php +++ b/src/MailtrapSandboxClient.php @@ -5,7 +5,7 @@ namespace Mailtrap; /** - * @method Api\Sandbox\Emails emails + * @method Api\Sandbox\Emails emails(int $inboxId) * @method Api\Sandbox\Project projects * @method Api\Sandbox\Inbox inboxes * @method Api\Sandbox\Attachment attachments @@ -13,7 +13,7 @@ * * Class MailtrapSandboxClient */ -final class MailtrapSandboxClient extends AbstractMailtrapClient +final class MailtrapSandboxClient extends AbstractMailtrapClient implements EmailsSendMailtrapClientInterface { public const API_MAPPING = [ 'emails' => Api\Sandbox\Emails::class, diff --git a/src/MailtrapSendingClient.php b/src/MailtrapSendingClient.php index d53d6e1..ef49f8c 100644 --- a/src/MailtrapSendingClient.php +++ b/src/MailtrapSendingClient.php @@ -5,11 +5,11 @@ namespace Mailtrap; /** - * @method Api\Sending\Emails emails + * @method Api\Sending\Emails emails() * * Class MailtrapSendingClient */ -final class MailtrapSendingClient extends AbstractMailtrapClient +final class MailtrapSendingClient extends AbstractMailtrapClient implements EmailsSendMailtrapClientInterface { public const API_MAPPING = [ 'emails' => Api\Sending\Emails::class, diff --git a/tests/Api/Sandbox/EmailsTest.php b/tests/Api/Sandbox/EmailsTest.php index 0b87bd7..baf54fa 100644 --- a/tests/Api/Sandbox/EmailsTest.php +++ b/tests/Api/Sandbox/EmailsTest.php @@ -32,7 +32,7 @@ protected function setUp(): void $this->email = $this->getMockBuilder(Emails::class) ->onlyMethods(['httpPost']) - ->setConstructorArgs([$this->getConfigMock()]) + ->setConstructorArgs([$this->getConfigMock(), self::FAKE_INBOX_ID]) ->getMock() ; } @@ -46,7 +46,6 @@ protected function tearDown(): void public function testValidSendToSandBox(): void { - $inboxId = 1000001; $expectedData = [ "success" => true, "message_ids" => [ @@ -70,7 +69,7 @@ public function testValidSendToSandBox(): void $this->email ->expects($this->once()) ->method('httpPost') - ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . $inboxId, [], [ + ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . self::FAKE_INBOX_ID, [], [ 'from' => [ 'email' => 'foo@example.com', 'name' => 'Ms. Foo Bar', @@ -93,7 +92,7 @@ public function testValidSendToSandBox(): void ]) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->email->send($email, $inboxId); + $response = $this->email->send($email); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -104,7 +103,6 @@ public function testValidSendToSandBox(): void public function testValidSendTemplateToSandbox(): void { - $inboxId = 1000001; $expectedData = [ "success" => true, "message_ids" => [ @@ -129,7 +127,7 @@ public function testValidSendTemplateToSandbox(): void $this->email ->expects($this->once()) ->method('httpPost') - ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . $inboxId, [], [ + ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . self::FAKE_INBOX_ID, [], [ 'from' => [ 'email' => 'foo@example.com', 'name' => 'Ms. Foo Bar', @@ -149,7 +147,7 @@ public function testValidSendTemplateToSandbox(): void ]) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->email->send($email, $inboxId); + $response = $this->email->send($email); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); diff --git a/tests/Bridge/Transport/MailtrapApiTransportTest.php b/tests/Bridge/Transport/MailtrapApiTransportTest.php index 47f41c8..6e2479a 100644 --- a/tests/Bridge/Transport/MailtrapApiTransportTest.php +++ b/tests/Bridge/Transport/MailtrapApiTransportTest.php @@ -7,6 +7,8 @@ use Mailtrap\Api\AbstractApi; use Mailtrap\Bridge\Transport\MailtrapApiTransport; use Mailtrap\Config; +use Mailtrap\MailtrapBulkSendingClient; +use Mailtrap\MailtrapSandboxClient; use Mailtrap\MailtrapSendingClient; use Mailtrap\Tests\MailtrapTestCase; use Symfony\Component\Mailer\Envelope; @@ -37,22 +39,32 @@ public function testToString(MailtrapApiTransport $transport, string $expected): public static function getTransportData(): array { + $sendConfig = (new Config('key'))->setHost(AbstractApi::SENDMAIL_TRANSACTIONAL_HOST); + $sandboxConfig = (new Config('key'))->setHost(AbstractApi::SENDMAIL_SANDBOX_HOST); + $bulkConfig = (new Config('key'))->setHost(AbstractApi::SENDMAIL_BULK_HOST); + $inboxId = 1234; + return [ [ new MailtrapApiTransport( - new MailtrapSendingClient( - (new Config('key'))->setHost(AbstractApi::SENDMAIL_TRANSACTIONAL_HOST) - ) + (new MailtrapSendingClient($sendConfig))->emails(), + $sendConfig + ), + sprintf('mailtrap+api://%s', AbstractApi::SENDMAIL_TRANSACTIONAL_HOST), + ], + [ + new MailtrapApiTransport( + (new MailtrapSandboxClient($sandboxConfig))->emails($inboxId), + $sandboxConfig ), - 'mailtrap+api://send.api.mailtrap.io', + sprintf('mailtrap+api://%s?inboxId=%s', AbstractApi::SENDMAIL_SANDBOX_HOST, $inboxId), ], [ new MailtrapApiTransport( - new MailtrapSendingClient( - (new Config('key'))->setHost(AbstractApi::SENDMAIL_SANDBOX_HOST) - ) + (new MailtrapBulkSendingClient($bulkConfig))->emails(), + $bulkConfig ), - 'mailtrap+api://sandbox.api.mailtrap.io', + sprintf('mailtrap+api://%s', AbstractApi::SENDMAIL_BULK_HOST), ], ]; } diff --git a/tests/Bridge/Transport/MailtrapTransportFactoryTest.php b/tests/Bridge/Transport/MailtrapTransportFactoryTest.php index b88d403..59d459a 100644 --- a/tests/Bridge/Transport/MailtrapTransportFactoryTest.php +++ b/tests/Bridge/Transport/MailtrapTransportFactoryTest.php @@ -53,16 +53,23 @@ public function createProvider(): iterable { $dispatcher = $this->getDispatcher(); $logger = $this->getLogger(); + $psrClient = new Psr18Client($this->getClient()); + $sendConfig = (new Config(self::USER)) + ->setHttpClient($psrClient) + ->setHost(AbstractApi::SENDMAIL_TRANSACTIONAL_HOST); + $sandboxConfig = (new Config(self::USER)) + ->setHttpClient($psrClient) + ->setHost(AbstractApi::SENDMAIL_SANDBOX_HOST); + $bulkConfig = (new Config(self::USER)) + ->setHttpClient($psrClient) + ->setHost(AbstractApi::SENDMAIL_BULK_HOST); + $inboxId = 1234; yield [ new Dsn('mailtrap+api', 'default', self::USER), new MailtrapApiTransport( - (new MailtrapClient( - (new Config(self::USER)) - ->setHttpClient(new Psr18Client($this->getClient())) - ->setHost(AbstractApi::SENDMAIL_TRANSACTIONAL_HOST) - ))->sending(), - null, + (new MailtrapClient($sendConfig))->sending()->emails(), + $sendConfig, $dispatcher, $logger ), @@ -71,12 +78,8 @@ public function createProvider(): iterable yield [ new Dsn('mailtrap', AbstractApi::SENDMAIL_TRANSACTIONAL_HOST, self::USER), new MailtrapApiTransport( - (new MailtrapClient( - (new Config(self::USER)) - ->setHttpClient(new Psr18Client($this->getClient())) - ->setHost(AbstractApi::SENDMAIL_TRANSACTIONAL_HOST) - ))->sending(), - null, + (new MailtrapClient($sendConfig))->sending()->emails(), + $sendConfig, $dispatcher, $logger ), @@ -86,12 +89,8 @@ public function createProvider(): iterable yield [ new Dsn('mailtrap+api', AbstractApi::SENDMAIL_SANDBOX_HOST, self::USER, null, null, ['inboxId' => 1234]), new MailtrapApiTransport( - (new MailtrapClient( - (new Config(self::USER)) - ->setHttpClient(new Psr18Client($this->getClient())) - ->setHost(AbstractApi::SENDMAIL_SANDBOX_HOST) - ))->sandbox(), - 1234, + (new MailtrapClient($sandboxConfig))->sandbox()->emails($inboxId), + $sandboxConfig, $dispatcher, $logger ), @@ -100,12 +99,8 @@ public function createProvider(): iterable yield [ new Dsn('mailtrap', AbstractApi::SENDMAIL_SANDBOX_HOST, self::USER, null, null, ['inboxId' => 1234]), new MailtrapApiTransport( - (new MailtrapClient( - (new Config(self::USER)) - ->setHttpClient(new Psr18Client($this->getClient())) - ->setHost(AbstractApi::SENDMAIL_SANDBOX_HOST) - ))->sandbox(), - 1234, + (new MailtrapClient($sandboxConfig))->sandbox()->emails($inboxId), + $sandboxConfig, $dispatcher, $logger ), @@ -115,12 +110,8 @@ public function createProvider(): iterable yield [ new Dsn('mailtrap+api', AbstractApi::SENDMAIL_BULK_HOST, self::USER), new MailtrapApiTransport( - (new MailtrapClient( - (new Config(self::USER)) - ->setHttpClient(new Psr18Client($this->getClient())) - ->setHost(AbstractApi::SENDMAIL_BULK_HOST) - ))->bulkSending(), - null, + (new MailtrapClient($bulkConfig))->bulkSending()->emails(), + $bulkConfig, $dispatcher, $logger ), @@ -129,12 +120,8 @@ public function createProvider(): iterable yield [ new Dsn('mailtrap', AbstractApi::SENDMAIL_BULK_HOST, self::USER), new MailtrapApiTransport( - (new MailtrapClient( - (new Config(self::USER)) - ->setHttpClient(new Psr18Client($this->getClient())) - ->setHost(AbstractApi::SENDMAIL_BULK_HOST) - ))->bulkSending(), - null, + (new MailtrapClient($bulkConfig))->bulkSending()->emails(), + $bulkConfig, $dispatcher, $logger ), diff --git a/tests/Bridge/Transport/TransportFactoryTestCase.php b/tests/Bridge/Transport/TransportFactoryTestCase.php index 0d04f1e..6630160 100644 --- a/tests/Bridge/Transport/TransportFactoryTestCase.php +++ b/tests/Bridge/Transport/TransportFactoryTestCase.php @@ -4,6 +4,7 @@ namespace Mailtrap\Tests\Bridge\Transport; +use Mailtrap\Api\AbstractApi; use Mailtrap\Tests\MailtrapTestCase; use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\Exception\IncompleteDsnException; @@ -58,8 +59,11 @@ public function testCreate(Dsn $dsn, TransportInterface $transport): void $factory = $this->getFactory(); $this->assertEquals($transport, $factory->create($dsn)); - if (str_contains('smtp', $dsn->getScheme())) { - $this->assertStringMatchesFormat($dsn->getScheme().'://%S'.$dsn->getHost().'%S', (string) $transport); + + if ('default' === $dsn->getHost()) { + $this->assertStringMatchesFormat('mailtrap+api://' . AbstractApi::SENDMAIL_TRANSACTIONAL_HOST, (string) $transport); + } else { + $this->assertStringStartsWith('mailtrap+api://' . $dsn->getHost(), (string) $transport); } } diff --git a/tests/MailtrapSandboxClientTest.php b/tests/MailtrapSandboxClientTest.php index 0c24305..8de9b5e 100644 --- a/tests/MailtrapSandboxClientTest.php +++ b/tests/MailtrapSandboxClientTest.php @@ -26,8 +26,11 @@ public function getLayerInterfaceClassName(): string public function mapInstancesProvider(): iterable { - foreach (MailtrapSandboxClient::API_MAPPING as $item) { - yield [new $item($this->getConfigMock())]; + foreach (MailtrapSandboxClient::API_MAPPING as $key => $item) { + yield match ($key) { + 'emails' => [new $item($this->getConfigMock(), self::FAKE_INBOX_ID)], + default => [new $item($this->getConfigMock())], + }; } } } From 1a7aa7bd655f17654bbfca98040323224ef5c2aa Mon Sep 17 00:00:00 2001 From: gaalferov Date: Tue, 21 May 2024 15:22:10 +0200 Subject: [PATCH 09/23] sandbox email fix examples --- examples/testing/emails.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/testing/emails.php b/examples/testing/emails.php index 94d029a..858fb04 100644 --- a/examples/testing/emails.php +++ b/examples/testing/emails.php @@ -69,8 +69,8 @@ ->add(new CategoryHeader('Integration Test')) ; - // Required param -> inbox_id - $response = $mailtrap->sandbox()->emails()->send($email, 1000001); // <--- you should use your inbox_id here (otherwise you will get 401) + // Required param -> inbox_id in emails() method + $response = $mailtrap->sandbox()->emails(1000001)->send($email); // print all possible information from the response var_dump($response->getHeaders()); //headers (array) @@ -110,7 +110,7 @@ ; // Required param -> inbox_id - $response = $mailtrap->sandbox()->emails()->send($email, 1000001); // <--- you should use your inbox_id here (otherwise you will get 401) + $response = $mailtrap->sandbox()->emails(1000001)->send($email); // <--- you should use your inbox_id here (otherwise you will get 401) var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { From 3a03d059f96ce297b7dfb8e531db83269843ba51 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Tue, 21 May 2024 15:33:12 +0200 Subject: [PATCH 10/23] add tests for unsupported hosts --- .../Transport/MailtrapTransportFactoryTest.php | 6 ++++++ .../Transport/TransportFactoryTestCase.php | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/Bridge/Transport/MailtrapTransportFactoryTest.php b/tests/Bridge/Transport/MailtrapTransportFactoryTest.php index 59d459a..65f41bd 100644 --- a/tests/Bridge/Transport/MailtrapTransportFactoryTest.php +++ b/tests/Bridge/Transport/MailtrapTransportFactoryTest.php @@ -140,4 +140,10 @@ public function incompleteDsnProvider(): iterable { yield [new Dsn('mailtrap+api', 'default')]; } + + public function unsupportedHostsProvider(): iterable + { + yield [new Dsn('mailtrap', 'invalid_url.api.mailtrap.io', self::USER)]; + yield [new Dsn('mailtrap', 'mailtrap.io', self::USER)]; + } } diff --git a/tests/Bridge/Transport/TransportFactoryTestCase.php b/tests/Bridge/Transport/TransportFactoryTestCase.php index 6630160..12c60a7 100644 --- a/tests/Bridge/Transport/TransportFactoryTestCase.php +++ b/tests/Bridge/Transport/TransportFactoryTestCase.php @@ -5,6 +5,7 @@ namespace Mailtrap\Tests\Bridge\Transport; use Mailtrap\Api\AbstractApi; +use Mailtrap\Exception\Transport\UnsupportedHostException; use Mailtrap\Tests\MailtrapTestCase; use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\Exception\IncompleteDsnException; @@ -41,6 +42,11 @@ public function incompleteDsnProvider(): iterable return []; } + public function unsupportedHostsProvider(): iterable + { + return []; + } + /** * @dataProvider supportsProvider */ @@ -82,6 +88,18 @@ public function testUnsupportedSchemeException(Dsn $dsn, string $message = null) $factory->create($dsn); } + /** + * @dataProvider unsupportedHostsProvider + */ + public function testUnsupportedHostsException(Dsn $dsn): void + { + $factory = $this->getFactory(); + + $this->expectException(UnsupportedHostException::class); + + $factory->create($dsn); + } + /** * @dataProvider incompleteDsnProvider */ From dc6aa8e03e271624b7fbe4a933c62f880b733355 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 22 May 2024 15:20:12 +0200 Subject: [PATCH 11/23] add short method to get the Email layer depends on config params --- README.md | 34 +++++++++++++++---- examples/sending/emails.php | 29 ++++++++++------ examples/testing/emails.php | 21 +++++++----- .../Transport/MailtrapTransportFactory.php | 1 - src/MailtrapClient.php | 26 ++++++++++++++ tests/MailtrapBulkSendingClientTest.php | 18 ++++++++++ tests/MailtrapSandboxClientTest.php | 10 ++++++ tests/MailtrapSendingClientTest.php | 10 ++++++ 8 files changed, 122 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 4b8a9f3..0f7d35b 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,10 @@ use Symfony\Component\Mime\Header\UnstructuredHeader; require __DIR__ . '/vendor/autoload.php'; -// your API token from here https://mailtrap.io/api-tokens -$apiKey = getenv('MAILTRAP_API_KEY'); -$mailtrap = new MailtrapClient(new Config($apiKey)); +// Mailtrap SENDING client (real) +$mailtrap = MailtrapClient::initSendingEmails( + apiKey: getenv('MAILTRAP_API_KEY') # your API token from here https://mailtrap.io/api-tokens +); $email = (new Email()) ->from(new Address('example@your-domain-here.com', 'Mailtrap Test')) @@ -89,22 +90,43 @@ $email = (new Email()) ; try { - $response = $mailtrap->sending()->emails()->send($email); // Email sending API (real) + $response = $mailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } -// OR send email to the Mailtrap SANDBOX +// OR -> Mailtrap BULK SENDING client (real) try { - $response = $mailtrap->sandbox()->emails()->send($email, 1000001); // Required second param -> inbox_id + $mailtrap = MailtrapClient::initSendingEmails( + apiKey: getenv('MAILTRAP_API_KEY'), # your API token from here https://mailtrap.io/api-tokens + isBulk: true # Bulk sending (@see https://help.mailtrap.io/article/113-sending-streams) + ); + + $response = $mailtrap->send($email); + + var_dump(ResponseHelper::toArray($response)); // body (array) +} catch (Exception $e) { + echo 'Caught exception: ', $e->getMessage(), "\n"; +} + +// OR -> Mailtrap SANDBOX client (testing) +try { + $mailtrap = MailtrapClient::initSendingEmails( + apiKey: getenv('MAILTRAP_API_KEY'), # your API token from here https://mailtrap.io/api-tokens + isSandbox: true, # Sandbox sending (@see https://help.mailtrap.io/article/109-getting-started-with-mailtrap-email-testing) + inboxId: getenv('MAILTRAP_INBOX_ID') # required param for sandbox sending + ); + + $response = $mailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } + ``` ### All usage examples diff --git a/examples/sending/emails.php b/examples/sending/emails.php index 2902063..79fa742 100644 --- a/examples/sending/emails.php +++ b/examples/sending/emails.php @@ -1,6 +1,5 @@ from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) @@ -70,7 +70,7 @@ ->add(new CategoryHeader('Integration Test')) ; - $response = $mailtrap->sending()->emails()->send($email); + $response = $mailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { @@ -88,8 +88,9 @@ */ try { // your API token from here https://mailtrap.io/api-tokens - $apiKey = getenv('MAILTRAP_API_KEY'); - $mailtrap = new MailtrapClient(new Config($apiKey)); + $mailtrap = MailtrapClient::initSendingEmails( + apiKey: getenv('MAILTRAP_API_KEY') + ); $email = (new Email()) ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) @@ -106,7 +107,7 @@ ->add(new TemplateVariableHeader('onboarding_video_link', 'some_video_link')) ; - $response = $mailtrap->sending()->emails()->send($email); + $response = $mailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { @@ -127,7 +128,10 @@ try { // your API token from here https://mailtrap.io/api-tokens $apiKey = getenv('MAILTRAP_API_KEY'); - $mailtrap = new MailtrapClient(new Config($apiKey)); + $mailtrap = MailtrapClient::initSendingEmails( + apiKey: getenv('MAILTRAP_API_KEY'), + isBulk: true # Bulk sending (@see https://help.mailtrap.io/article/113-sending-streams) + ); $email = (new Email()) ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) @@ -170,7 +174,7 @@ ->add(new CategoryHeader('Integration Test')) ; - $response = $mailtrap->bulkSending()->emails()->send($email); + $response = $mailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { @@ -189,7 +193,10 @@ try { // your API token from here https://mailtrap.io/api-tokens $apiKey = getenv('MAILTRAP_API_KEY'); - $mailtrap = new MailtrapClient(new Config($apiKey)); + $mailtrap = MailtrapClient::initSendingEmails( + apiKey: getenv('MAILTRAP_API_KEY'), + isBulk: true # Bulk sending (@see https://help.mailtrap.io/article/113-sending-streams) + ); $email = (new Email()) ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) @@ -206,7 +213,7 @@ ->add(new TemplateVariableHeader('onboarding_video_link', 'some_video_link')) ; - $response = $mailtrap->bulkSending()->emails()->send($email); + $response = $mailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { diff --git a/examples/testing/emails.php b/examples/testing/emails.php index 858fb04..5d9dd1e 100644 --- a/examples/testing/emails.php +++ b/examples/testing/emails.php @@ -1,6 +1,5 @@ from(new Address('mailtrap@example.com', 'Mailtrap Test')) @@ -69,8 +71,7 @@ ->add(new CategoryHeader('Integration Test')) ; - // Required param -> inbox_id in emails() method - $response = $mailtrap->sandbox()->emails(1000001)->send($email); + $response = $mailtrap->send($email); // print all possible information from the response var_dump($response->getHeaders()); //headers (array) @@ -91,8 +92,11 @@ */ try { // your API token from here https://mailtrap.io/api-tokens - $apiKey = getenv('MAILTRAP_API_KEY'); - $mailtrap = new MailtrapClient(new Config($apiKey)); + $mailtrap = MailtrapClient::initSendingEmails( + apiKey: getenv('MAILTRAP_API_KEY'), + isSandbox: true, # Sandbox sending (@see https://help.mailtrap.io/article/109-getting-started-with-mailtrap-email-testing) + inboxId: getenv('MAILTRAP_INBOX_ID') # required param for sandbox sending + ); $email = (new Email()) ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use the domain which is linked to template UUID (otherwise you will get 401) @@ -109,8 +113,7 @@ ->add(new TemplateVariableHeader('onboarding_video_link', 'some_video_link')) ; - // Required param -> inbox_id - $response = $mailtrap->sandbox()->emails(1000001)->send($email); // <--- you should use your inbox_id here (otherwise you will get 401) + $response = $mailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { diff --git a/src/Bridge/Transport/MailtrapTransportFactory.php b/src/Bridge/Transport/MailtrapTransportFactory.php index 10a5e29..eb30ebe 100644 --- a/src/Bridge/Transport/MailtrapTransportFactory.php +++ b/src/Bridge/Transport/MailtrapTransportFactory.php @@ -10,7 +10,6 @@ use Mailtrap\Exception\RuntimeException; use Mailtrap\Exception\Transport\UnsupportedHostException; use Mailtrap\MailtrapClient; -use Mailtrap\MailtrapClientInterface; use Mailtrap\MailtrapSandboxClient; use Symfony\Component\HttpClient\Psr18Client; use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; diff --git a/src/MailtrapClient.php b/src/MailtrapClient.php index dc3f7fd..3274da4 100644 --- a/src/MailtrapClient.php +++ b/src/MailtrapClient.php @@ -4,6 +4,9 @@ namespace Mailtrap; +use Mailtrap\Api\EmailsSendApiInterface; +use Mailtrap\Exception\InvalidArgumentException; + /** * The main entry point to use all possible API layers * @@ -27,4 +30,27 @@ class MailtrapClient extends AbstractMailtrapClient self::LAYER_TRANSACTIONAL_SENDING => MailtrapSendingClient::class, self::LAYER_BULK_SENDING => MailtrapBulkSendingClient::class, ]; + + public static function initSendingEmails( + string $apiKey, + bool $isBulk = false, + bool $isSandbox = false, + int $inboxId = null, + ): EmailsSendApiInterface { + $client = new self(new Config($apiKey)); + + if ($isBulk && $isSandbox) { + throw new InvalidArgumentException('Bulk mode is not applicable for sandbox API'); + } + + if ($isSandbox) { + return $client->sandbox()->emails($inboxId); + } + + if ($isBulk) { + return $client->bulkSending()->emails(); + } + + return $client->sending()->emails(); + } } diff --git a/tests/MailtrapBulkSendingClientTest.php b/tests/MailtrapBulkSendingClientTest.php index e9d566c..81a4462 100644 --- a/tests/MailtrapBulkSendingClientTest.php +++ b/tests/MailtrapBulkSendingClientTest.php @@ -5,7 +5,10 @@ namespace Mailtrap\Tests; use Mailtrap\Api\BulkSending\BulkSendingInterface; +use Mailtrap\Api\BulkSending\Emails as BulkSendingEmails; +use Mailtrap\Exception\InvalidArgumentException; use Mailtrap\MailtrapBulkSendingClient; +use Mailtrap\MailtrapClient; /** * @covers MailtrapBulkSendingClientTest @@ -30,4 +33,19 @@ public function mapInstancesProvider(): iterable yield [new $item($this->getConfigMock())]; } } + + public function testValidInitBulkSendingEmails(): void + { + $this->assertInstanceOf( + BulkSendingEmails::class, + MailtrapClient::initSendingEmails(apiKey: self::DEFAULT_API_KEY, isBulk: true) + ); + } + + public function testInValidInitBulkSendingEmails(): void + { + $this->expectException(InvalidArgumentException::class); + + MailtrapClient::initSendingEmails(apiKey: self::DEFAULT_API_KEY, isBulk: true, isSandbox: true); + } } diff --git a/tests/MailtrapSandboxClientTest.php b/tests/MailtrapSandboxClientTest.php index 8de9b5e..71a7f42 100644 --- a/tests/MailtrapSandboxClientTest.php +++ b/tests/MailtrapSandboxClientTest.php @@ -4,7 +4,9 @@ namespace Mailtrap\Tests; +use Mailtrap\Api\Sandbox\Emails as SandboxSendingEmails; use Mailtrap\Api\Sandbox\SandboxInterface; +use Mailtrap\MailtrapClient; use Mailtrap\MailtrapSandboxClient; /** @@ -33,4 +35,12 @@ public function mapInstancesProvider(): iterable }; } } + + public function testValidInitSandboxSendingEmails(): void + { + $this->assertInstanceOf( + SandboxSendingEmails::class, + MailtrapClient::initSendingEmails(apiKey: self::DEFAULT_API_KEY, isSandbox: true, inboxId: self::FAKE_INBOX_ID) + ); + } } diff --git a/tests/MailtrapSendingClientTest.php b/tests/MailtrapSendingClientTest.php index 2c5005b..419cdd2 100644 --- a/tests/MailtrapSendingClientTest.php +++ b/tests/MailtrapSendingClientTest.php @@ -4,7 +4,9 @@ namespace Mailtrap\Tests; +use Mailtrap\Api\Sending\Emails as TransactionSendingEmails; use Mailtrap\Api\Sending\SendingInterface; +use Mailtrap\MailtrapClient; use Mailtrap\MailtrapSendingClient; /** @@ -30,4 +32,12 @@ public function mapInstancesProvider(): iterable yield [new $item($this->getConfigMock())]; } } + + public function testValidInitTransactionSendingEmails(): void + { + $this->assertInstanceOf( + TransactionSendingEmails::class, + MailtrapClient::initSendingEmails(apiKey: self::DEFAULT_API_KEY) + ); + } } From 474656d0cd7c6da40d596b08aa5f2df8f81f269a Mon Sep 17 00:00:00 2001 From: gaalferov Date: Thu, 23 May 2024 19:28:12 +0200 Subject: [PATCH 12/23] Rebuild Sandbox Projects layers to use the account ID at the client level + tests --- examples/testing/projects.php | 24 ++++++++-------------- src/Api/Sandbox/Project.php | 32 ++++++++++++++--------------- src/MailtrapSandboxClient.php | 2 +- tests/Api/Sandbox/ProjectTest.php | 16 +++++++-------- tests/MailtrapSandboxClientTest.php | 1 + 5 files changed, 35 insertions(+), 40 deletions(-) diff --git a/examples/testing/projects.php b/examples/testing/projects.php index 2b1c4f6..ed4dc3f 100644 --- a/examples/testing/projects.php +++ b/examples/testing/projects.php @@ -2,13 +2,13 @@ use Mailtrap\Config; use Mailtrap\Helper\ResponseHelper; -use Mailtrap\MailtrapClient; +use Mailtrap\MailtrapSandboxClient; require __DIR__ . '/../vendor/autoload.php'; -// your API token from here https://mailtrap.io/api-tokens -$apiKey = getenv('MAILTRAP_API_KEY'); -$mailtrap = new MailtrapClient(new Config($apiKey)); +$accountId = getenv('MAILTRAP_ACCOUNT_ID'); +$config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens +$sandboxProjects = (new MailtrapSandboxClient($config))->projects($accountId); #required parameter is accountId /** * List projects and their inboxes to which the API token has access. @@ -16,9 +16,7 @@ * GET https://mailtrap.io/api/accounts/{account_id}/projects */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - - $response = $mailtrap->sandbox()->projects()->getList($accountId); + $response = $sandboxProjects->getList(); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -33,10 +31,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/projects/{project_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $projectId = getenv('MAILTRAP_PROJECT_ID'); - $response = $mailtrap->sandbox()->projects()->getById($accountId, $projectId); + $response = $sandboxProjects->getById($projectId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -51,10 +48,9 @@ * POST https://mailtrap.io/api/accounts/{account_id}/projects */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $projectName = 'Some project name'; - $response = $mailtrap->sandbox()->projects()->create($accountId, $projectName); + $response = $sandboxProjects->create($projectName); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -70,11 +66,10 @@ * PATCH https://mailtrap.io/api/accounts/{account_id}/projects/{project_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $projectId = getenv('MAILTRAP_PROJECT_ID'); $newProjectName = 'New project name'; - $response = $mailtrap->sandbox()->projects()->updateName($accountId, $projectId, $newProjectName); + $response = $sandboxProjects->updateName($projectId, $newProjectName); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -89,10 +84,9 @@ * DELETE https://mailtrap.io/api/accounts/{account_id}/projects/{project_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $projectId = getenv('MAILTRAP_PROJECT_ID'); - $response = $mailtrap->sandbox()->projects()->delete($accountId, $projectId); + $response = $sandboxProjects->delete($projectId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); diff --git a/src/Api/Sandbox/Project.php b/src/Api/Sandbox/Project.php index ff5052a..d6125e5 100644 --- a/src/Api/Sandbox/Project.php +++ b/src/Api/Sandbox/Project.php @@ -5,6 +5,7 @@ namespace Mailtrap\Api\Sandbox; use Mailtrap\Api\AbstractApi; +use Mailtrap\ConfigInterface; use Psr\Http\Message\ResponseInterface; /** @@ -12,47 +13,48 @@ */ class Project extends AbstractApi implements SandboxInterface { + public function __construct(ConfigInterface $config, private int $accountId) + { + parent::__construct($config); + } + /** * List projects and their inboxes to which the API token has access. * - * @param int $accountId - * * @return ResponseInterface */ - public function getList(int $accountId): ResponseInterface + public function getList(): ResponseInterface { return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/projects', $this->getHost(), $accountId) + sprintf('%s/api/accounts/%s/projects', $this->getHost(), $this->accountId) )); } /** * Get the project and its inboxes. * - * @param int $accountId * @param int $projectId * * @return ResponseInterface */ - public function getById(int $accountId, int $projectId): ResponseInterface + public function getById(int $projectId): ResponseInterface { return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $accountId, $projectId) + sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->accountId, $projectId) )); } /** * Create a project * - * @param int $accountId * @param string $projectName * * @return ResponseInterface */ - public function create(int $accountId, string $projectName): ResponseInterface + public function create(string $projectName): ResponseInterface { return $this->handleResponse($this->httpPost( - sprintf('%s/api/accounts/%s/projects', $this->getHost(), $accountId), + sprintf('%s/api/accounts/%s/projects', $this->getHost(), $this->accountId), [], ['project' => ['name' => $projectName]] )); @@ -61,31 +63,29 @@ public function create(int $accountId, string $projectName): ResponseInterface /** * Delete project and its inboxes. * - * @param int $accountId * @param int $projectId * * @return ResponseInterface */ - public function delete(int $accountId, int $projectId): ResponseInterface + public function delete(int $projectId): ResponseInterface { return $this->handleResponse($this->httpDelete( - sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $accountId, $projectId) + sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->accountId, $projectId) )); } /** * Update project name. * - * @param int $accountId * @param int $projectId * @param string $projectName * * @return ResponseInterface */ - public function updateName(int $accountId, int $projectId, string $projectName): ResponseInterface + public function updateName(int $projectId, string $projectName): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $accountId, $projectId), + sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->accountId, $projectId), [], ['project' => ['name' => $projectName]] )); diff --git a/src/MailtrapSandboxClient.php b/src/MailtrapSandboxClient.php index c4114a2..007dd3f 100644 --- a/src/MailtrapSandboxClient.php +++ b/src/MailtrapSandboxClient.php @@ -6,7 +6,7 @@ /** * @method Api\Sandbox\Emails emails(int $inboxId) - * @method Api\Sandbox\Project projects + * @method Api\Sandbox\Project projects(int $accountId) * @method Api\Sandbox\Inbox inboxes * @method Api\Sandbox\Attachment attachments * @method Api\Sandbox\Message messages diff --git a/tests/Api/Sandbox/ProjectTest.php b/tests/Api/Sandbox/ProjectTest.php index 80eec3e..270934b 100644 --- a/tests/Api/Sandbox/ProjectTest.php +++ b/tests/Api/Sandbox/ProjectTest.php @@ -27,7 +27,7 @@ protected function setUp(): void $this->project = $this->getMockBuilder(Project::class) ->onlyMethods(['httpGet', 'httpPost', 'httpPatch', 'httpDelete']) - ->setConstructorArgs([$this->getConfigMock()]) + ->setConstructorArgs([$this->getConfigMock(), self::FAKE_ACCOUNT_ID]) ->getMock() ; } @@ -46,7 +46,7 @@ public function testValidGetList(): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/projects') ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedData()))); - $response = $this->project->getList(self::FAKE_ACCOUNT_ID); + $response = $this->project->getList(); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -61,7 +61,7 @@ public function testValidGetById(): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/projects/' . self::FAKE_PROJECT_ID) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedData()[1]))); - $response = $this->project->getById(self::FAKE_ACCOUNT_ID, self::FAKE_PROJECT_ID); + $response = $this->project->getById(self::FAKE_PROJECT_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -99,7 +99,7 @@ public function testValidCreate(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->project->create(self::FAKE_ACCOUNT_ID, $expectedData['name']); + $response = $this->project->create($expectedData['name']); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -126,7 +126,7 @@ public function testInvalidCreate(): void 'Errors: name -> is too short (minimum is 2 characters).' ); - $this->project->create(self::FAKE_ACCOUNT_ID, 'a'); + $this->project->create('a'); } public function testValidDelete(): void @@ -136,7 +136,7 @@ public function testValidDelete(): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/projects/' . self::FAKE_PROJECT_ID) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode(['id' => self::FAKE_PROJECT_ID]))); - $response = $this->project->delete(self::FAKE_ACCOUNT_ID, self::FAKE_PROJECT_ID); + $response = $this->project->delete(self::FAKE_PROJECT_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -172,7 +172,7 @@ public function testValidUpdateName(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->project->updateName(self::FAKE_ACCOUNT_ID, self::FAKE_PROJECT_ID, $expectedData['name']); + $response = $this->project->updateName(self::FAKE_PROJECT_ID, $expectedData['name']); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -204,7 +204,7 @@ public function testInvalidUpdateName(): void 'Errors: name -> is too long (maximum is 100 characters).' ); - $this->project->updateName(self::FAKE_ACCOUNT_ID, self::FAKE_PROJECT_ID, $longName); + $this->project->updateName(self::FAKE_PROJECT_ID, $longName); } private function getExpectedData(): array diff --git a/tests/MailtrapSandboxClientTest.php b/tests/MailtrapSandboxClientTest.php index 71a7f42..871f91b 100644 --- a/tests/MailtrapSandboxClientTest.php +++ b/tests/MailtrapSandboxClientTest.php @@ -31,6 +31,7 @@ public function mapInstancesProvider(): iterable foreach (MailtrapSandboxClient::API_MAPPING as $key => $item) { yield match ($key) { 'emails' => [new $item($this->getConfigMock(), self::FAKE_INBOX_ID)], + 'projects' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID)], default => [new $item($this->getConfigMock())], }; } From ed79530a00c019495b3d4e4d9fbf6b375a94af63 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Mon, 27 May 2024 16:39:16 +0200 Subject: [PATCH 13/23] Rebuild Sandbox Messages layers to use the account ID at the client level + tests --- examples/testing/messages.php | 54 +++++----------- examples/testing/projects.php | 1 + src/Api/Sandbox/Message.php | 99 ++++++++++++++--------------- src/Api/Sandbox/Project.php | 15 +++-- src/MailtrapSandboxClient.php | 2 +- tests/Api/Sandbox/MessageTest.php | 26 ++++---- tests/MailtrapSandboxClientTest.php | 1 + 7 files changed, 89 insertions(+), 109 deletions(-) diff --git a/examples/testing/messages.php b/examples/testing/messages.php index 48bea08..72fc609 100644 --- a/examples/testing/messages.php +++ b/examples/testing/messages.php @@ -2,13 +2,16 @@ use Mailtrap\Config; use Mailtrap\Helper\ResponseHelper; -use Mailtrap\MailtrapClient; +use Mailtrap\MailtrapSandboxClient; require __DIR__ . '/../vendor/autoload.php'; // your API token from here https://mailtrap.io/api-tokens -$apiKey = getenv('MAILTRAP_API_KEY'); -$mailtrap = new MailtrapClient(new Config($apiKey)); +$accountId = getenv('MAILTRAP_ACCOUNT_ID'); +$inboxId = getenv('MAILTRAP_INBOX_ID'); +$config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens + +$sandboxMessages = (new MailtrapSandboxClient($config))->messages($accountId, $inboxId); #required parameters are accountId amd inboxId /** * Get messages @@ -17,15 +20,12 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); - // not required parameters $page = 1; // by default 30 messages per page $search = 'hello'; // it works like case insensitive pattern matching by subject, to_email, to_name $lastMessageId = 3000000003; // get emails, where primary key is less then this param (does not work with page param) - $response = $mailtrap->sandbox()->messages()->getList($accountId, $inboxId); + $response = $sandboxMessages->getList(); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -40,11 +40,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->getById($accountId, $inboxId, $messageId); + $response = $sandboxMessages->getById($messageId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -59,11 +57,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/body.htmlsource */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->getSource($accountId, $inboxId, $messageId); + $response = $sandboxMessages->getSource($messageId); // print the response body (string) var_dump(ResponseHelper::toString($response)); @@ -78,11 +74,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/body.eml */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->getEml($accountId, $inboxId, $messageId); + $response = $sandboxMessages->getEml($messageId); // print the response body (string) var_dump(ResponseHelper::toString($response)); @@ -97,11 +91,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/body.html */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->getHtml($accountId, $inboxId, $messageId); + $response = $sandboxMessages->getHtml($messageId); // print the response body (string) var_dump(ResponseHelper::toString($response)); @@ -116,11 +108,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/body.raw */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->getRaw($accountId, $inboxId, $messageId); + $response = $sandboxMessages->getRaw($messageId); // print the response body (string) var_dump(ResponseHelper::toString($response)); @@ -135,11 +125,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/body.txt */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->getText($accountId, $inboxId, $messageId); + $response = $sandboxMessages->getText($messageId); // print the response body (string) var_dump(ResponseHelper::toString($response)); @@ -154,11 +142,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/analyze */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->getHtmlAnalysis($accountId, $inboxId, $messageId); + $response = $sandboxMessages->getHtmlAnalysis($messageId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -173,11 +159,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/spam_report */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->getSpamScore($accountId, $inboxId, $messageId); + $response = $sandboxMessages->getSpamScore($messageId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -192,11 +176,9 @@ * PATCH https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->markAsRead($accountId, $inboxId, $messageId); + $response = $sandboxMessages->markAsRead($messageId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -211,11 +193,9 @@ * DELETE https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_INBOX_MESSAGE_ID'); - $response = $mailtrap->sandbox()->messages()->delete($accountId, $inboxId, $messageId); + $response = $sandboxMessages->delete($messageId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); diff --git a/examples/testing/projects.php b/examples/testing/projects.php index ed4dc3f..6eba93d 100644 --- a/examples/testing/projects.php +++ b/examples/testing/projects.php @@ -8,6 +8,7 @@ $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens + $sandboxProjects = (new MailtrapSandboxClient($config))->projects($accountId); #required parameter is accountId /** diff --git a/src/Api/Sandbox/Message.php b/src/Api/Sandbox/Message.php index a9d7dfe..9e8ee53 100644 --- a/src/Api/Sandbox/Message.php +++ b/src/Api/Sandbox/Message.php @@ -5,6 +5,7 @@ namespace Mailtrap\Api\Sandbox; use Mailtrap\Api\AbstractApi; +use Mailtrap\ConfigInterface; use Psr\Http\Message\ResponseInterface; /** @@ -12,13 +13,19 @@ */ class Message extends AbstractApi implements SandboxInterface { + public function __construct( + ConfigInterface $config, + private int $accountId, + private int $inboxId, + ) { + parent::__construct($config); + } + /** * Get all messages in the inbox * Note: if you want to get all messages you need to use "page" param (by default will return only 30 messages per * page) * - * @param int $accountId - * @param int $inboxId * @param int|null $page page of emails (per page = 30 messages, does not work with last_id param) * @param string|null $search filter emails by this key; it works like case insensitive * pattern matching by subject, to_email, to_name, namely if any of these fields @@ -29,8 +36,6 @@ class Message extends AbstractApi implements SandboxInterface * @return ResponseInterface */ public function getList( - int $accountId, - int $inboxId, ?int $page = null, ?string $search = null, ?int $lastMessageId = null @@ -50,7 +55,7 @@ public function getList( } return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/inboxes/%s/messages', $this->getHost(), $accountId, $inboxId), + sprintf('%s/api/accounts/%s/inboxes/%s/messages', $this->getHost(), $this->getAccountId(), $this->getInboxId()), $parameters )); } @@ -58,35 +63,31 @@ public function getList( /** * Get email message by ID. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function getById(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function getById(int $messageId): ResponseInterface { return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/inboxes/%s/messages/%s', $this->getHost(), $accountId, $inboxId, $messageId) + sprintf('%s/api/accounts/%s/inboxes/%s/messages/%s', $this->getHost(), $this->getAccountId(), $this->getInboxId(), $messageId) )); } /** * Get a brief spam report by message ID. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function getSpamScore(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function getSpamScore(int $messageId): ResponseInterface { return $this->handleResponse($this->httpGet(sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/spam_report', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId ))); } @@ -94,19 +95,17 @@ public function getSpamScore(int $accountId, int $inboxId, int $messageId): Resp /** * Get a brief HTML report by message ID. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function getHtmlAnalysis(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function getHtmlAnalysis(int $messageId): ResponseInterface { return $this->handleResponse($this->httpGet(sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/analyze', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId ))); } @@ -114,19 +113,17 @@ public function getHtmlAnalysis(int $accountId, int $inboxId, int $messageId): R /** * Get text email body, if it exists. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function getText(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function getText(int $messageId): ResponseInterface { return $this->handleResponse($this->httpGet(sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/body.txt', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId ))); } @@ -134,19 +131,17 @@ public function getText(int $accountId, int $inboxId, int $messageId): ResponseI /** * Get raw email body. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function getRaw(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function getRaw(int $messageId): ResponseInterface { return $this->handleResponse($this->httpGet(sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/body.raw', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId ))); } @@ -154,19 +149,17 @@ public function getRaw(int $accountId, int $inboxId, int $messageId): ResponseIn /** * Get formatted HTML email body. Not applicable for plain text emails. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function getHtml(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function getHtml(int $messageId): ResponseInterface { return $this->handleResponse($this->httpGet(sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/body.html', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId ))); } @@ -174,19 +167,17 @@ public function getHtml(int $accountId, int $inboxId, int $messageId): ResponseI /** * Get email message in .eml format. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function getEml(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function getEml( int $messageId): ResponseInterface { return $this->handleResponse($this->httpGet(sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/body.eml', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId ))); } @@ -194,19 +185,17 @@ public function getEml(int $accountId, int $inboxId, int $messageId): ResponseIn /** * Get HTML source of email. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function getSource(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function getSource(int $messageId): ResponseInterface { return $this->handleResponse($this->httpGet(sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/body.htmlsource', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId ))); } @@ -214,17 +203,15 @@ public function getSource(int $accountId, int $inboxId, int $messageId): Respons /** * Update message attributes (right now only the is_read attribute is available for modification). * - * @param int $accountId - * @param int $inboxId * @param int $messageId * @param bool $isRead * * @return ResponseInterface */ - public function markAsRead(int $accountId, int $inboxId, int $messageId, bool $isRead = true): ResponseInterface + public function markAsRead(int $messageId, bool $isRead = true): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/inboxes/%s/messages/%s', $this->getHost(), $accountId, $inboxId, $messageId), + sprintf('%s/api/accounts/%s/inboxes/%s/messages/%s', $this->getHost(), $this->getAccountId(), $this->getInboxId(), $messageId), [], [ 'message' => [ @@ -237,16 +224,24 @@ public function markAsRead(int $accountId, int $inboxId, int $messageId, bool $i /** * Delete message from inbox. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * * @return ResponseInterface */ - public function delete(int $accountId, int $inboxId, int $messageId): ResponseInterface + public function delete(int $messageId): ResponseInterface { return $this->handleResponse($this->httpDelete( - sprintf('%s/api/accounts/%s/inboxes/%s/messages/%s', $this->getHost(), $accountId, $inboxId, $messageId) + sprintf('%s/api/accounts/%s/inboxes/%s/messages/%s', $this->getHost(), $this->getAccountId(), $this->getInboxId(), $messageId) )); } + + public function getAccountId(): int + { + return $this->accountId; + } + + public function getInboxId(): int + { + return $this->inboxId; + } } diff --git a/src/Api/Sandbox/Project.php b/src/Api/Sandbox/Project.php index d6125e5..e4dced0 100644 --- a/src/Api/Sandbox/Project.php +++ b/src/Api/Sandbox/Project.php @@ -26,7 +26,7 @@ public function __construct(ConfigInterface $config, private int $accountId) public function getList(): ResponseInterface { return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/projects', $this->getHost(), $this->accountId) + sprintf('%s/api/accounts/%s/projects', $this->getHost(), $this->getAccountId()) )); } @@ -40,7 +40,7 @@ public function getList(): ResponseInterface public function getById(int $projectId): ResponseInterface { return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->accountId, $projectId) + sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->getAccountId(), $projectId) )); } @@ -54,7 +54,7 @@ public function getById(int $projectId): ResponseInterface public function create(string $projectName): ResponseInterface { return $this->handleResponse($this->httpPost( - sprintf('%s/api/accounts/%s/projects', $this->getHost(), $this->accountId), + sprintf('%s/api/accounts/%s/projects', $this->getHost(), $this->getAccountId()), [], ['project' => ['name' => $projectName]] )); @@ -70,7 +70,7 @@ public function create(string $projectName): ResponseInterface public function delete(int $projectId): ResponseInterface { return $this->handleResponse($this->httpDelete( - sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->accountId, $projectId) + sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->getAccountId(), $projectId) )); } @@ -85,9 +85,14 @@ public function delete(int $projectId): ResponseInterface public function updateName(int $projectId, string $projectName): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->accountId, $projectId), + sprintf('%s/api/accounts/%s/projects/%s', $this->getHost(), $this->getAccountId(), $projectId), [], ['project' => ['name' => $projectName]] )); } + + public function getAccountId(): int + { + return $this->accountId; + } } diff --git a/src/MailtrapSandboxClient.php b/src/MailtrapSandboxClient.php index 007dd3f..000aada 100644 --- a/src/MailtrapSandboxClient.php +++ b/src/MailtrapSandboxClient.php @@ -9,7 +9,7 @@ * @method Api\Sandbox\Project projects(int $accountId) * @method Api\Sandbox\Inbox inboxes * @method Api\Sandbox\Attachment attachments - * @method Api\Sandbox\Message messages + * @method Api\Sandbox\Message messages(int $accountId, int $inboxId) * * Class MailtrapSandboxClient */ diff --git a/tests/Api/Sandbox/MessageTest.php b/tests/Api/Sandbox/MessageTest.php index ad064e2..75fbaae 100644 --- a/tests/Api/Sandbox/MessageTest.php +++ b/tests/Api/Sandbox/MessageTest.php @@ -27,7 +27,7 @@ protected function setUp(): void $this->message = $this->getMockBuilder(Message::class) ->onlyMethods(['httpGet', 'httpPatch', 'httpDelete']) - ->setConstructorArgs([$this->getConfigMock()]) + ->setConstructorArgs([$this->getConfigMock(), self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID]) ->getMock() ; } @@ -48,7 +48,7 @@ public function testValidGetList(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getMessagesData()))); - $response = $this->message->getList(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID); + $response = $this->message->getList(); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -74,8 +74,6 @@ public function testValidGetListWithFilters(): void ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); $response = $this->message->getList( - self::FAKE_ACCOUNT_ID, - self::FAKE_INBOX_ID, $page, $search, ); @@ -99,7 +97,7 @@ public function testGetById(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getMessagesData()[0]))); - $response = $this->message->getById(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->getById(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -120,7 +118,7 @@ public function testGetSpamScore($expectedData): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->message->getSpamScore(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->getSpamScore(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -139,7 +137,7 @@ public function testGetHtmlAnalysis($expectedData): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->message->getHtmlAnalysis(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->getHtmlAnalysis(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -156,7 +154,7 @@ public function testGetText(): void ) ->willReturn(new Response(200, ['Content-Type' => 'text/plain'], $expectedData)); - $response = $this->message->getText(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->getText(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toString($response); $this->assertInstanceOf(Response::class, $response); @@ -173,7 +171,7 @@ public function testGetRaw(): void ) ->willReturn(new Response(200, ['Content-Type' => 'text/plain'], $expectedData)); - $response = $this->message->getRaw(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->getRaw(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toString($response); $this->assertInstanceOf(Response::class, $response); @@ -190,7 +188,7 @@ public function testGetHtml(): void ) ->willReturn(new Response(200, ['Content-Type' => 'text/html'], $expectedData)); - $response = $this->message->getHtml(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->getHtml(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toString($response); $this->assertInstanceOf(Response::class, $response); @@ -207,7 +205,7 @@ public function testGetEml(): void ) ->willReturn(new Response(200, ['Content-Type' => 'message/rfc822'], $expectedData)); - $response = $this->message->getEml(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->getEml(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toString($response); $this->assertInstanceOf(Response::class, $response); @@ -224,7 +222,7 @@ public function testGeSource(): void ) ->willReturn(new Response(200, ['Content-Type' => 'text/html'], $expectedData)); - $response = $this->message->getSource(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->getSource(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toString($response); $this->assertInstanceOf(Response::class, $response); @@ -249,7 +247,7 @@ public function testMarkAsRead($expectedData, $isRead): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->message->markAsRead(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID, $expectedData['is_read']); + $response = $this->message->markAsRead(self::FAKE_MESSAGE_ID, $expectedData['is_read']); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -266,7 +264,7 @@ public function testDelete(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getMessagesData()[0]))); - $response = $this->message->delete(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID); + $response = $this->message->delete(self::FAKE_MESSAGE_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); diff --git a/tests/MailtrapSandboxClientTest.php b/tests/MailtrapSandboxClientTest.php index 871f91b..2e98881 100644 --- a/tests/MailtrapSandboxClientTest.php +++ b/tests/MailtrapSandboxClientTest.php @@ -32,6 +32,7 @@ public function mapInstancesProvider(): iterable yield match ($key) { 'emails' => [new $item($this->getConfigMock(), self::FAKE_INBOX_ID)], 'projects' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID)], + 'messages' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID)], default => [new $item($this->getConfigMock())], }; } From 51bd825dfcdb3359f75247d108e1491fbd76f391 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Mon, 27 May 2024 17:35:35 +0200 Subject: [PATCH 14/23] Rebuild Sandbox message Attachments layers to use the account ID and inbox ID at the client level --- examples/testing/attachments.php | 21 ++++++++--------- src/Api/Sandbox/Attachment.php | 35 +++++++++++++++++++--------- src/MailtrapSandboxClient.php | 2 +- tests/Api/Sandbox/AttachmentTest.php | 6 +---- tests/MailtrapSandboxClientTest.php | 2 +- 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/examples/testing/attachments.php b/examples/testing/attachments.php index ed07ffb..65cea4b 100644 --- a/examples/testing/attachments.php +++ b/examples/testing/attachments.php @@ -2,13 +2,17 @@ use Mailtrap\Config; use Mailtrap\Helper\ResponseHelper; -use Mailtrap\MailtrapClient; +use Mailtrap\MailtrapSandboxClient; require __DIR__ . '/../vendor/autoload.php'; // your API token from here https://mailtrap.io/api-tokens -$apiKey = getenv('MAILTRAP_API_KEY'); -$mailtrap = new MailtrapClient(new Config($apiKey)); +$accountId = getenv('MAILTRAP_ACCOUNT_ID'); +$inboxId = getenv('MAILTRAP_INBOX_ID'); +$config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens + +$sandboxAttachments = (new MailtrapSandboxClient($config))->attachments($accountId, $inboxId); #required parameters are accountId amd inboxId + /** * Get attachments @@ -16,13 +20,10 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/attachments */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_MESSAGE_ID'); - // optional (null|string) - $attachmentType = 'inline'; + $attachmentType = 'inline'; # optional (null|string) - $response = $mailtrap->sandbox()->attachments()->getMessageAttachments($accountId, $inboxId, $messageId, $attachmentType); + $response = $sandboxAttachments->getMessageAttachments($messageId, $attachmentType); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -36,12 +37,10 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/attachments/{attachment_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $inboxId = getenv('MAILTRAP_INBOX_ID'); $messageId = getenv('MAILTRAP_MESSAGE_ID'); $attachmentId = getenv('MAILTRAP_MESSAGE_ATTACHMENT_ID'); - $response = $mailtrap->sandbox()->attachments()->getMessageAttachment($accountId, $inboxId, $messageId, $attachmentId); + $response = $sandboxAttachments->getMessageAttachment($messageId, $attachmentId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); diff --git a/src/Api/Sandbox/Attachment.php b/src/Api/Sandbox/Attachment.php index 03b95c5..7297413 100644 --- a/src/Api/Sandbox/Attachment.php +++ b/src/Api/Sandbox/Attachment.php @@ -5,6 +5,7 @@ namespace Mailtrap\Api\Sandbox; use Mailtrap\Api\AbstractApi; +use Mailtrap\ConfigInterface; use Psr\Http\Message\ResponseInterface; /** @@ -12,19 +13,23 @@ */ class Attachment extends AbstractApi implements SandboxInterface { + public function __construct( + ConfigInterface $config, + private int $accountId, + private int $inboxId, + ) { + parent::__construct($config); + } + /** * Get message attachments by inboxId and messageId. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * @param string|null $attachmentType * * @return ResponseInterface */ public function getMessageAttachments( - int $accountId, - int $inboxId, int $messageId, string $attachmentType = null ): ResponseInterface { @@ -39,8 +44,8 @@ public function getMessageAttachments( sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/attachments', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId ), $parameters @@ -50,22 +55,30 @@ public function getMessageAttachments( /** * Get message single attachment by id. * - * @param int $accountId - * @param int $inboxId * @param int $messageId * @param int $attachmentId * * @return ResponseInterface */ - public function getMessageAttachment(int $accountId, int $inboxId, int $messageId, int $attachmentId): ResponseInterface + public function getMessageAttachment(int $messageId, int $attachmentId): ResponseInterface { return $this->handleResponse($this->httpGet(sprintf( '%s/api/accounts/%s/inboxes/%s/messages/%s/attachments/%s', $this->getHost(), - $accountId, - $inboxId, + $this->getAccountId(), + $this->getInboxId(), $messageId, $attachmentId ))); } + + public function getAccountId(): int + { + return $this->accountId; + } + + public function getInboxId(): int + { + return $this->inboxId; + } } diff --git a/src/MailtrapSandboxClient.php b/src/MailtrapSandboxClient.php index 000aada..cff9a12 100644 --- a/src/MailtrapSandboxClient.php +++ b/src/MailtrapSandboxClient.php @@ -8,7 +8,7 @@ * @method Api\Sandbox\Emails emails(int $inboxId) * @method Api\Sandbox\Project projects(int $accountId) * @method Api\Sandbox\Inbox inboxes - * @method Api\Sandbox\Attachment attachments + * @method Api\Sandbox\Attachment attachments(int $accountId, int $inboxId) * @method Api\Sandbox\Message messages(int $accountId, int $inboxId) * * Class MailtrapSandboxClient diff --git a/tests/Api/Sandbox/AttachmentTest.php b/tests/Api/Sandbox/AttachmentTest.php index f460f9a..92a3a38 100644 --- a/tests/Api/Sandbox/AttachmentTest.php +++ b/tests/Api/Sandbox/AttachmentTest.php @@ -27,7 +27,7 @@ protected function setUp(): void $this->attachment = $this->getMockBuilder(Attachment::class) ->onlyMethods(['httpGet']) - ->setConstructorArgs([$this->getConfigMock()]) + ->setConstructorArgs([$this->getConfigMock(), self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID]) ->getMock() ; } @@ -59,8 +59,6 @@ public function testGetMessageAttachments(): void ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedData()))); $response = $this->attachment->getMessageAttachments( - self::FAKE_ACCOUNT_ID, - self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID, $attachmentType ); @@ -86,8 +84,6 @@ public function testGetMessageAttachment(): void ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedData()))); $response = $this->attachment->getMessageAttachment( - self::FAKE_ACCOUNT_ID, - self::FAKE_INBOX_ID, self::FAKE_MESSAGE_ID, self::FAKE_MESSAGE_ATTACHMENT_ID ); diff --git a/tests/MailtrapSandboxClientTest.php b/tests/MailtrapSandboxClientTest.php index 2e98881..e4c0ff0 100644 --- a/tests/MailtrapSandboxClientTest.php +++ b/tests/MailtrapSandboxClientTest.php @@ -32,7 +32,7 @@ public function mapInstancesProvider(): iterable yield match ($key) { 'emails' => [new $item($this->getConfigMock(), self::FAKE_INBOX_ID)], 'projects' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID)], - 'messages' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID)], + 'messages', 'attachments' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID)], default => [new $item($this->getConfigMock())], }; } From 4d173f7f2f7f18b1a6aae16a859811ca2d04b6d1 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Mon, 27 May 2024 18:16:55 +0200 Subject: [PATCH 15/23] Rebuild Sandbox Inboxes layers to use the account ID at the client level --- examples/testing/inboxes.php | 40 +++++++------------ src/Api/Sandbox/Inbox.php | 62 ++++++++++++++--------------- src/MailtrapSandboxClient.php | 2 +- tests/Api/Sandbox/InboxTest.php | 24 +++++------ tests/MailtrapSandboxClientTest.php | 2 +- 5 files changed, 59 insertions(+), 71 deletions(-) diff --git a/examples/testing/inboxes.php b/examples/testing/inboxes.php index a3b1467..86aa962 100644 --- a/examples/testing/inboxes.php +++ b/examples/testing/inboxes.php @@ -3,14 +3,14 @@ use Mailtrap\Config; use Mailtrap\DTO\Request\Inbox; use Mailtrap\Helper\ResponseHelper; -use Mailtrap\MailtrapClient; +use Mailtrap\MailtrapSandboxClient; require __DIR__ . '/../vendor/autoload.php'; -// your API token from here https://mailtrap.io/api-tokens -$apiKey = getenv('MAILTRAP_API_KEY'); -$mailtrap = new MailtrapClient(new Config($apiKey)); +$accountId = getenv('MAILTRAP_ACCOUNT_ID'); +$config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens +$sandboxInboxes = (new MailtrapSandboxClient($config))->inboxes($accountId); #required parameter is accountId /** * Get a list of inboxes. @@ -18,9 +18,7 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - - $response = $mailtrap->sandbox()->inboxes()->getList($accountId); + $response = $sandboxInboxes->getList(); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -35,11 +33,10 @@ * POST https://mailtrap.io/api/accounts/{account_id}/projects/{project_id}/inboxes */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $projectId = getenv('MAILTRAP_PROJECT_ID'); $inboxName = 'First inbox'; - $response = $mailtrap->sandbox()->inboxes()->create($accountId, $projectId, $inboxName); + $response = $sandboxInboxes->create($projectId, $inboxName); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -54,10 +51,9 @@ * GET https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); - $response = $mailtrap->sandbox()->inboxes()->getInboxAttributes($accountId, $inboxId); + $response = $sandboxInboxes->getInboxAttributes($inboxId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -72,10 +68,9 @@ * DELETE https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); - $response = $mailtrap->sandbox()->inboxes()->delete($accountId, $inboxId); + $response = $sandboxInboxes->delete($inboxId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -90,10 +85,9 @@ * PATCH https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/reset_email_username */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); - $response = $mailtrap->sandbox()->inboxes()->resetEmailAddress($accountId, $inboxId); + $response = $sandboxInboxes->resetEmailAddress($inboxId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -108,10 +102,9 @@ * PATCH https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/toggle_email_username */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); - $response = $mailtrap->sandbox()->inboxes()->toggleEmailAddress($accountId, $inboxId); + $response = $sandboxInboxes->toggleEmailAddress($inboxId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -126,10 +119,9 @@ * PATCH https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/reset_credentials */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); - $response = $mailtrap->sandbox()->inboxes()->resetSmtpCredentials($accountId, $inboxId); + $response = $sandboxInboxes->resetSmtpCredentials($inboxId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -144,10 +136,9 @@ * PATCH https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/all_read */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); - $response = $mailtrap->sandbox()->inboxes()->markAsRead($accountId, $inboxId); + $response = $sandboxInboxes->markAsRead($inboxId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -162,10 +153,9 @@ * PATCH https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id}/clean */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); - $response = $mailtrap->sandbox()->inboxes()->clean($accountId, $inboxId); + $response = $sandboxInboxes->clean($inboxId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -180,13 +170,11 @@ * PATCH https://mailtrap.io/api/accounts/{account_id}/inboxes/{inbox_id} */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); $newInboxName = 'New inbox name'; $newEmailUsername = 'new-email-username'; - $response = $mailtrap->sandbox()->inboxes()->update( - $accountId, + $response = $sandboxInboxes->update( $inboxId, new Inbox($newInboxName, $newEmailUsername) ); diff --git a/src/Api/Sandbox/Inbox.php b/src/Api/Sandbox/Inbox.php index aeeb003..d649bd8 100644 --- a/src/Api/Sandbox/Inbox.php +++ b/src/Api/Sandbox/Inbox.php @@ -5,6 +5,7 @@ namespace Mailtrap\Api\Sandbox; use Mailtrap\Api\AbstractApi; +use Mailtrap\ConfigInterface; use Mailtrap\DTO\Request\Inbox as InboxRequest; use Mailtrap\Exception\RuntimeException; use Psr\Http\Message\ResponseInterface; @@ -14,49 +15,50 @@ */ class Inbox extends AbstractApi implements SandboxInterface { + public function __construct(ConfigInterface $config, private int $accountId) + { + parent::__construct($config); + } + /** * Get a list of inboxes. * - * @param int $accountId - * * @return ResponseInterface */ - public function getList(int $accountId): ResponseInterface + public function getList(): ResponseInterface { return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/inboxes', $this->getHost(), $accountId) + sprintf('%s/api/accounts/%s/inboxes', $this->getHost(), $this->getAccountId()) )); } /** * Get inbox attributes by inbox id. See the list of attributes in the example * - * @param int $accountId * @param int $inboxId * * @return ResponseInterface */ - public function getInboxAttributes(int $accountId, int $inboxId): ResponseInterface + public function getInboxAttributes(int $inboxId): ResponseInterface { return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/inboxes/%s', $this->getHost(), $accountId, $inboxId) + sprintf('%s/api/accounts/%s/inboxes/%s', $this->getHost(), $this->getAccountId(), $inboxId) )); } /** * Create an inbox in a project. * - * @param int $accountId * @param int $projectId * @param string $inboxName * * @return ResponseInterface */ - public function create(int $accountId, int $projectId, string $inboxName): ResponseInterface + public function create(int $projectId, string $inboxName): ResponseInterface { return $this->handleResponse( $this->httpPost( - sprintf('%s/api/accounts/%s/projects/%s/inboxes', $this->getHost(), $accountId, $projectId), + sprintf('%s/api/accounts/%s/projects/%s/inboxes', $this->getHost(), $this->getAccountId(), $projectId), [], ['inbox' => ['name' => $inboxName]] ) @@ -66,31 +68,29 @@ public function create(int $accountId, int $projectId, string $inboxName): Respo /** * Delete an inbox with all its emails. * - * @param int $accountId * @param int $inboxId * * @return ResponseInterface */ - public function delete(int $accountId, int $inboxId): ResponseInterface + public function delete(int $inboxId): ResponseInterface { return $this->handleResponse($this->httpDelete( - sprintf('%s/api/accounts/%s/inboxes/%s', $this->getHost(), $accountId, $inboxId) + sprintf('%s/api/accounts/%s/inboxes/%s', $this->getHost(), $this->getAccountId(), $inboxId) )); } /** * Update inbox name and/or inbox email username. * - * @param int $accountId * @param int $inboxId * @param InboxRequest $updateInbox * * @return ResponseInterface */ - public function update(int $accountId, int $inboxId, InboxRequest $updateInbox): ResponseInterface + public function update(int $inboxId, InboxRequest $updateInbox): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/inboxes/%s', $this->getHost(), $accountId, $inboxId), + sprintf('%s/api/accounts/%s/inboxes/%s', $this->getHost(), $this->getAccountId(), $inboxId), [], ['inbox' => $this->getUpdatePayload($updateInbox)] )); @@ -99,75 +99,70 @@ public function update(int $accountId, int $inboxId, InboxRequest $updateInbox): /** * Delete all messages (emails) from inbox. * - * @param int $accountId * @param int $inboxId * * @return ResponseInterface */ - public function clean(int $accountId, int $inboxId): ResponseInterface + public function clean(int $inboxId): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/inboxes/%s/clean', $this->getHost(), $accountId, $inboxId) + sprintf('%s/api/accounts/%s/inboxes/%s/clean', $this->getHost(), $this->getAccountId(), $inboxId) )); } /** * Mark all messages in the inbox as read. * - * @param int $accountId * @param int $inboxId * * @return ResponseInterface */ - public function markAsRead(int $accountId, int $inboxId): ResponseInterface + public function markAsRead(int $inboxId): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/inboxes/%s/all_read', $this->getHost(), $accountId, $inboxId) + sprintf('%s/api/accounts/%s/inboxes/%s/all_read', $this->getHost(), $this->getAccountId(), $inboxId) )); } /** * Reset SMTP credentials of the inbox. * - * @param int $accountId * @param int $inboxId * * @return ResponseInterface */ - public function resetSmtpCredentials(int $accountId, int $inboxId): ResponseInterface + public function resetSmtpCredentials(int $inboxId): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/inboxes/%s/reset_credentials', $this->getHost(), $accountId, $inboxId) + sprintf('%s/api/accounts/%s/inboxes/%s/reset_credentials', $this->getHost(), $this->getAccountId(), $inboxId) )); } /** * Turn the email address of the inbox on/off. * - * @param int $accountId * @param int $inboxId * * @return ResponseInterface */ - public function toggleEmailAddress(int $accountId, int $inboxId): ResponseInterface + public function toggleEmailAddress(int $inboxId): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/inboxes/%s/toggle_email_username', $this->getHost(), $accountId, $inboxId) + sprintf('%s/api/accounts/%s/inboxes/%s/toggle_email_username', $this->getHost(), $this->getAccountId(), $inboxId) )); } /** * Reset username of email address per inbox. * - * @param int $accountId * @param int $inboxId * * @return ResponseInterface */ - public function resetEmailAddress(int $accountId, int $inboxId): ResponseInterface + public function resetEmailAddress(int $inboxId): ResponseInterface { return $this->handleResponse($this->httpPatch( - sprintf('%s/api/accounts/%s/inboxes/%s/reset_email_username', $this->getHost(), $accountId, $inboxId) + sprintf('%s/api/accounts/%s/inboxes/%s/reset_email_username', $this->getHost(), $this->getAccountId(), $inboxId) )); } @@ -180,4 +175,9 @@ private function getUpdatePayload(InboxRequest $updateInbox): array return $result; } + + public function getAccountId(): int + { + return $this->accountId; + } } diff --git a/src/MailtrapSandboxClient.php b/src/MailtrapSandboxClient.php index cff9a12..7194bc6 100644 --- a/src/MailtrapSandboxClient.php +++ b/src/MailtrapSandboxClient.php @@ -7,7 +7,7 @@ /** * @method Api\Sandbox\Emails emails(int $inboxId) * @method Api\Sandbox\Project projects(int $accountId) - * @method Api\Sandbox\Inbox inboxes + * @method Api\Sandbox\Inbox inboxes(int $accountId) * @method Api\Sandbox\Attachment attachments(int $accountId, int $inboxId) * @method Api\Sandbox\Message messages(int $accountId, int $inboxId) * diff --git a/tests/Api/Sandbox/InboxTest.php b/tests/Api/Sandbox/InboxTest.php index d0e1967..5cbbb0e 100644 --- a/tests/Api/Sandbox/InboxTest.php +++ b/tests/Api/Sandbox/InboxTest.php @@ -28,7 +28,7 @@ protected function setUp(): void $this->inbox = $this->getMockBuilder(Inbox::class) ->onlyMethods(['httpGet', 'httpPost', 'httpPatch', 'httpDelete']) - ->setConstructorArgs([$this->getConfigMock()]) + ->setConstructorArgs([$this->getConfigMock(), self::FAKE_ACCOUNT_ID]) ->getMock() ; } @@ -47,7 +47,7 @@ public function testGetList(): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/inboxes') ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedInboxData()))); - $response = $this->inbox->getList(self::FAKE_ACCOUNT_ID); + $response = $this->inbox->getList(); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -62,7 +62,7 @@ public function testGetInboxAttributes(): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/inboxes/' . self::FAKE_INBOX_ID) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedInboxData()[0]))); - $response = $this->inbox->getInboxAttributes(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID); + $response = $this->inbox->getInboxAttributes(self::FAKE_INBOX_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -122,7 +122,7 @@ public function testValidCreate(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->inbox->create(self::FAKE_ACCOUNT_ID, self::FAKE_PROJECT_ID, $expectedData['name']); + $response = $this->inbox->create(self::FAKE_PROJECT_ID, $expectedData['name']); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -151,7 +151,7 @@ public function testInvalidCreate(): void 'Errors: name -> can\'t be blank.' ); - $this->inbox->create(self::FAKE_ACCOUNT_ID, self::FAKE_PROJECT_ID, 'a'); + $this->inbox->create(self::FAKE_PROJECT_ID, 'a'); } public function testValidDelete(): void @@ -163,7 +163,7 @@ public function testValidDelete(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedInboxData()[0]))); - $response = $this->inbox->delete(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID); + $response = $this->inbox->delete(self::FAKE_INBOX_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -224,7 +224,7 @@ public function testUpdate(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->inbox->update(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID, $inboxRequest); + $response = $this->inbox->update(self::FAKE_INBOX_ID, $inboxRequest); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -243,7 +243,7 @@ public function testClean(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedInboxData()[0]))); - $response = $this->inbox->clean(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID); + $response = $this->inbox->clean(self::FAKE_INBOX_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -260,7 +260,7 @@ public function testMarkAsRead(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedInboxData()[0]))); - $response = $this->inbox->markAsRead(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID); + $response = $this->inbox->markAsRead(self::FAKE_INBOX_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -280,7 +280,7 @@ public function testResetSmtpCredentials(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->inbox->resetSmtpCredentials(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID); + $response = $this->inbox->resetSmtpCredentials(self::FAKE_INBOX_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -302,7 +302,7 @@ public function testToggleEmailAddress(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->inbox->toggleEmailAddress(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID); + $response = $this->inbox->toggleEmailAddress(self::FAKE_INBOX_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -323,7 +323,7 @@ public function testResetEmailAddress(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); - $response = $this->inbox->resetEmailAddress(self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID); + $response = $this->inbox->resetEmailAddress(self::FAKE_INBOX_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); diff --git a/tests/MailtrapSandboxClientTest.php b/tests/MailtrapSandboxClientTest.php index e4c0ff0..0f72582 100644 --- a/tests/MailtrapSandboxClientTest.php +++ b/tests/MailtrapSandboxClientTest.php @@ -31,7 +31,7 @@ public function mapInstancesProvider(): iterable foreach (MailtrapSandboxClient::API_MAPPING as $key => $item) { yield match ($key) { 'emails' => [new $item($this->getConfigMock(), self::FAKE_INBOX_ID)], - 'projects' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID)], + 'projects', 'inboxes' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID)], 'messages', 'attachments' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID, self::FAKE_INBOX_ID)], default => [new $item($this->getConfigMock())], }; From 9e1a5e2c92602fe9ddeca63cb6c2bf4de84df40c Mon Sep 17 00:00:00 2001 From: gaalferov Date: Tue, 28 May 2024 19:32:42 +0200 Subject: [PATCH 16/23] Rebuild General Accounts&Permissions&Users layers --- examples/general/accounts.php | 9 ++++----- examples/general/permissions.php | 14 ++++++-------- examples/general/users.php | 16 +++++++--------- src/Api/General/Permission.php | 22 +++++++++++++++------- src/Api/General/User.php | 21 +++++++++++++++------ src/MailtrapGeneralClient.php | 6 +++--- tests/Api/General/PermissionTest.php | 14 +++++++------- tests/Api/General/UserTest.php | 18 +++++++++--------- tests/MailtrapGeneralClientTest.php | 7 +++++-- 9 files changed, 71 insertions(+), 56 deletions(-) diff --git a/examples/general/accounts.php b/examples/general/accounts.php index 8ea287d..a512063 100644 --- a/examples/general/accounts.php +++ b/examples/general/accounts.php @@ -2,13 +2,12 @@ use Mailtrap\Config; use Mailtrap\Helper\ResponseHelper; -use Mailtrap\MailtrapClient; +use Mailtrap\MailtrapGeneralClient; require __DIR__ . '/../vendor/autoload.php'; -// your API token from here https://mailtrap.io/api-tokens -$apiKey = getenv('MAILTRAP_API_KEY'); -$mailtrap = new MailtrapClient(new Config($apiKey)); +$config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens +$generalAccounts = (new MailtrapGeneralClient($config))->accounts(); /** * Get a list of your Mailtrap accounts. @@ -16,7 +15,7 @@ * GET https://mailtrap.io/api/accounts */ try { - $response = $mailtrap->general()->accounts()->getList(); + $response = $generalAccounts->getList(); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { diff --git a/examples/general/permissions.php b/examples/general/permissions.php index b90dcc5..014f3a4 100644 --- a/examples/general/permissions.php +++ b/examples/general/permissions.php @@ -6,13 +6,13 @@ use Mailtrap\DTO\Request\Permission\PermissionInterface; use Mailtrap\DTO\Request\Permission\Permissions; use Mailtrap\Helper\ResponseHelper; -use Mailtrap\MailtrapClient; +use Mailtrap\MailtrapGeneralClient; require __DIR__ . '/../vendor/autoload.php'; -// your API token from here https://mailtrap.io/api-tokens -$apiKey = getenv('MAILTRAP_API_KEY'); -$mailtrap = new MailtrapClient(new Config($apiKey)); +$accountId = getenv('MAILTRAP_ACCOUNT_ID'); +$config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens +$generalPermissions = (new MailtrapGeneralClient($config))->permissions($accountId); /** * Get resources @@ -20,8 +20,7 @@ * GET https://mailtrap.io/api/accounts/{account_id}/permissions/resources */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); - $response = $mailtrap->general()->permissions()->getResources($accountId); + $response = $generalPermissions->getResources(); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -39,7 +38,6 @@ * PUT https://mailtrap.io/api/accounts/{account_id}/account_accesses/{account_access_id}/permissions/bulk */ try { - $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $accountAccessId = getenv('MAILTRAP_ACCOUNT_ACCESS_ID'); // resource IDs @@ -53,7 +51,7 @@ new DestroyPermission($destroyProjectResourceId, PermissionInterface::TYPE_PROJECT), ); - $response = $mailtrap->general()->permissions()->update($accountId, $accountAccessId, $permissions); + $response = $generalPermissions->update($accountAccessId, $permissions); // print the response body (array) var_dump(ResponseHelper::toArray($response)); diff --git a/examples/general/users.php b/examples/general/users.php index 68f121a..1ed7063 100644 --- a/examples/general/users.php +++ b/examples/general/users.php @@ -2,13 +2,13 @@ use Mailtrap\Config; use Mailtrap\Helper\ResponseHelper; -use Mailtrap\MailtrapClient; +use Mailtrap\MailtrapGeneralClient; require __DIR__ . '/../vendor/autoload.php'; -// your API token from here https://mailtrap.io/api-tokens -$apiKey = getenv('MAILTRAP_API_KEY'); -$mailtrap = new MailtrapClient(new Config($apiKey)); +$accountId = getenv('MAILTRAP_ACCOUNT_ID'); +$config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens +$generalUsers = (new MailtrapGeneralClient($config))->users($accountId); /** * List all users in account @@ -16,13 +16,12 @@ * GET https://mailtrap.io/api/accounts/{account_id}/account_accesses */ try { - $accountId = 1000001; - $response = $mailtrap->general()->users()->getList($accountId); + $response = $generalUsers->getList(); // OR with query parameters (not required) $inboxIds = [2000005, 2000006]; $projectIds = [1005001]; - $response = $mailtrap->general()->users()->getList($accountId, $inboxIds, $projectIds); + $response = $generalUsers->getList($inboxIds, $projectIds); // print the response body (array) var_dump(ResponseHelper::toArray($response)); @@ -36,10 +35,9 @@ * DELETE https://mailtrap.io/api/accounts/{account_id}/account_accesses/{account_access_id} */ try { - $accountId = 1000001; $accountAccessId = 10000009; - $response = $mailtrap->general()->users()->delete($accountId, $accountAccessId); + $response = $generalUsers->delete($accountAccessId); // print the response body (array) var_dump(ResponseHelper::toArray($response)); diff --git a/src/Api/General/Permission.php b/src/Api/General/Permission.php index 270f421..c8e673f 100644 --- a/src/Api/General/Permission.php +++ b/src/Api/General/Permission.php @@ -5,6 +5,7 @@ namespace Mailtrap\Api\General; use Mailtrap\Api\AbstractApi; +use Mailtrap\ConfigInterface; use Mailtrap\DTO\Request\Permission\Permissions; use Mailtrap\Exception\RuntimeException; use Psr\Http\Message\ResponseInterface; @@ -14,17 +15,20 @@ */ class Permission extends AbstractApi implements GeneralInterface { + public function __construct(ConfigInterface $config, private int $accountId) + { + parent::__construct($config); + } + /** * Get all resources in your account (Inboxes, Projects, Domains, Billing and Account itself) to which the token has admin access. * - * @param int $accountId - * * @return ResponseInterface */ - public function getResources(int $accountId): ResponseInterface + public function getResources(): ResponseInterface { return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/permissions/resources', $this->getHost(), $accountId) + sprintf('%s/api/accounts/%s/permissions/resources', $this->getHost(), $this->getAccountId()) )); } @@ -33,21 +37,25 @@ public function getResources(int $accountId): ResponseInterface * If you send a combination of resource_type and resource_id that already exists, the permission is updated. * If the combination doesn’t exist, the permission is created. * - * @param int $accountId * @param int $accountAccessId * @param Permissions $permissions * * @return ResponseInterface */ - public function update(int $accountId, int $accountAccessId, Permissions $permissions): ResponseInterface + public function update(int $accountAccessId, Permissions $permissions): ResponseInterface { return $this->handleResponse($this->httpPut( - sprintf('%s/api/accounts/%s/account_accesses/%s/permissions/bulk', $this->getHost(), $accountId, $accountAccessId), + sprintf('%s/api/accounts/%s/account_accesses/%s/permissions/bulk', $this->getHost(), $this->getAccountId(), $accountAccessId), [], ['permissions' => $this->getPayload($permissions)] )); } + public function getAccountId(): int + { + return $this->accountId; + } + private function getPayload(Permissions $permissions): array { $payload = []; diff --git a/src/Api/General/User.php b/src/Api/General/User.php index 5ae419a..e50c758 100644 --- a/src/Api/General/User.php +++ b/src/Api/General/User.php @@ -5,6 +5,7 @@ namespace Mailtrap\Api\General; use Mailtrap\Api\AbstractApi; +use Mailtrap\ConfigInterface; use Psr\Http\Message\ResponseInterface; /** @@ -12,17 +13,21 @@ */ class User extends AbstractApi implements GeneralInterface { + public function __construct(ConfigInterface $config, private int $accountId) + { + parent::__construct($config); + } + /** * Get list of all account users. You need to have account admin or owner permissions for this endpoint to work. * If you specify project_ids, inbox_ids, the endpoint returns users filtered by these resources. * - * @param int $accountId * @param array $inboxIds * @param array $projectIds * * @return ResponseInterface */ - public function getList(int $accountId, array $inboxIds = [], array $projectIds = []): ResponseInterface + public function getList(array $inboxIds = [], array $projectIds = []): ResponseInterface { $parameters = []; if (count($inboxIds) > 0) { @@ -34,7 +39,7 @@ public function getList(int $accountId, array $inboxIds = [], array $projectIds } return $this->handleResponse($this->httpGet( - sprintf('%s/api/accounts/%s/account_accesses', $this->getHost(), $accountId), + sprintf('%s/api/accounts/%s/account_accesses', $this->getHost(), $this->getAccountId()), $parameters )); } @@ -42,15 +47,19 @@ public function getList(int $accountId, array $inboxIds = [], array $projectIds /** * Remove user by their ID. You need to be an account admin/owner for this endpoint to work. * - * @param int $accountId * @param int $accountAccessId * * @return ResponseInterface */ - public function delete(int $accountId, int $accountAccessId): ResponseInterface + public function delete(int $accountAccessId): ResponseInterface { return $this->handleResponse($this->httpDelete( - sprintf('%s/api/accounts/%s/account_accesses/%s', $this->getHost(), $accountId, $accountAccessId) + sprintf('%s/api/accounts/%s/account_accesses/%s', $this->getHost(), $this->getAccountId(), $accountAccessId) )); } + + public function getAccountId(): int + { + return $this->accountId; + } } diff --git a/src/MailtrapGeneralClient.php b/src/MailtrapGeneralClient.php index 4ec7906..37c35fc 100644 --- a/src/MailtrapGeneralClient.php +++ b/src/MailtrapGeneralClient.php @@ -5,9 +5,9 @@ namespace Mailtrap; /** - * @method Api\General\Account accounts - * @method Api\General\User users - * @method Api\General\Permission permissions + * @method Api\General\Account accounts() + * @method Api\General\User users(int $accountId) + * @method Api\General\Permission permissions(int $accountId) * * Class MailtrapGeneralClient */ diff --git a/tests/Api/General/PermissionTest.php b/tests/Api/General/PermissionTest.php index fd9b976..3756680 100644 --- a/tests/Api/General/PermissionTest.php +++ b/tests/Api/General/PermissionTest.php @@ -32,7 +32,7 @@ protected function setUp(): void $this->permission = $this->getMockBuilder(Permission::class) ->onlyMethods(['httpGet', 'httpPut']) - ->setConstructorArgs([$this->getConfigMock()]) + ->setConstructorArgs([$this->getConfigMock(), self::FAKE_ACCOUNT_ID]) ->getMock() ; } @@ -51,7 +51,7 @@ public function testValidGetResources(): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/permissions/resources') ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedData()))); - $response = $this->permission->getResources(self::FAKE_ACCOUNT_ID); + $response = $this->permission->getResources(); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -71,7 +71,7 @@ public function test401InvalidGetResources(): void 'Unauthorized. Make sure you are sending correct credentials with the request before retrying. Errors: Incorrect API token.' ); - $this->permission->getResources(self::FAKE_ACCOUNT_ID); + $this->permission->getResources(); } public function test403InvalidGetResources(): void @@ -86,7 +86,7 @@ public function test403InvalidGetResources(): void 'Forbidden. Make sure domain verification process is completed or check your permissions. Errors: Access forbidden.' ); - $this->permission->getResources(self::FAKE_ACCOUNT_ID); + $this->permission->getResources(); } /** @@ -99,7 +99,7 @@ public function testValidUpdate($permissions): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/account_accesses/' . self::FAKE_ACCOUNT_ACCESS_ID . '/permissions/bulk') ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode(['message' => 'Permissions have been updated!']))); - $response = $this->permission->update(self::FAKE_ACCOUNT_ID, self::FAKE_ACCOUNT_ACCESS_ID, $permissions); + $response = $this->permission->update(self::FAKE_ACCOUNT_ACCESS_ID, $permissions); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -115,7 +115,7 @@ public function testInvalidUpdate(): void ); $emptyPermissions = new Permissions(); - $this->permission->update(self::FAKE_ACCOUNT_ID, self::FAKE_ACCOUNT_ACCESS_ID, $emptyPermissions); + $this->permission->update(self::FAKE_ACCOUNT_ACCESS_ID, $emptyPermissions); } /** @@ -125,7 +125,7 @@ public function testValidGetPayload($permissions, $expectedResult): void { $method = new \ReflectionMethod(Permission::class, 'getPayload'); $method->setAccessible(true); - $payload = $method->invoke(new Permission($this->getConfigMock()), $permissions); + $payload = $method->invoke(new Permission($this->getConfigMock(), self::FAKE_ACCOUNT_ID), $permissions); $this->assertEquals($expectedResult, $payload); } diff --git a/tests/Api/General/UserTest.php b/tests/Api/General/UserTest.php index bdf5f83..2d8e7f9 100644 --- a/tests/Api/General/UserTest.php +++ b/tests/Api/General/UserTest.php @@ -30,7 +30,7 @@ protected function setUp(): void $this->user = $this->getMockBuilder(User::class) ->onlyMethods(['httpGet', 'httpDelete']) - ->setConstructorArgs([$this->getConfigMock()]) + ->setConstructorArgs([$this->getConfigMock(), self::FAKE_ACCOUNT_ID]) ->getMock() ; } @@ -49,7 +49,7 @@ public function testValidGetListWithoutFilters(): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/account_accesses') ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($this->getExpectedData()))); - $response = $this->user->getList(self::FAKE_ACCOUNT_ID); + $response = $this->user->getList(); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -71,7 +71,7 @@ public function testValidGetListWithFilters(): void ) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode(array_slice($expectedResult, 1)))); - $response = $this->user->getList(self::FAKE_ACCOUNT_ID, $inboxIds, $projectIds); + $response = $this->user->getList($inboxIds, $projectIds); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -91,7 +91,7 @@ public function test401InvalidGetList(): void 'Unauthorized. Make sure you are sending correct credentials with the request before retrying. Errors: Incorrect API token.' ); - $this->user->getList(self::FAKE_ACCOUNT_ID); + $this->user->getList(); } public function test403InvalidGetList(): void @@ -106,7 +106,7 @@ public function test403InvalidGetList(): void 'Forbidden. Make sure domain verification process is completed or check your permissions. Errors: Access forbidden.' ); - $this->user->getList(self::FAKE_ACCOUNT_ID); + $this->user->getList(); } public function testValidRemove(): void @@ -116,7 +116,7 @@ public function testValidRemove(): void ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/account_accesses/' . self::FAKE_ACCOUNT_ACCESS_ID) ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode(['id' => self::FAKE_ACCOUNT_ACCESS_ID]))); - $response = $this->user->delete(self::FAKE_ACCOUNT_ID, self::FAKE_ACCOUNT_ACCESS_ID); + $response = $this->user->delete(self::FAKE_ACCOUNT_ACCESS_ID); $responseData = ResponseHelper::toArray($response); $this->assertInstanceOf(Response::class, $response); @@ -136,7 +136,7 @@ public function test401InvalidRemove(): void 'Unauthorized. Make sure you are sending correct credentials with the request before retrying. Errors: Incorrect API token.' ); - $this->user->delete(self::FAKE_ACCOUNT_ID, self::FAKE_ACCOUNT_ACCESS_ID); + $this->user->delete(self::FAKE_ACCOUNT_ACCESS_ID); } public function test403InvalidRemove(): void @@ -151,7 +151,7 @@ public function test403InvalidRemove(): void 'Forbidden. Make sure domain verification process is completed or check your permissions. Errors: Access forbidden.' ); - $this->user->delete(self::FAKE_ACCOUNT_ID, self::FAKE_ACCOUNT_ACCESS_ID); + $this->user->delete(self::FAKE_ACCOUNT_ACCESS_ID); } public function test404InvalidRemove(): void @@ -166,7 +166,7 @@ public function test404InvalidRemove(): void 'The requested entity has not been found. Errors: Not Found.' ); - $this->user->delete(self::FAKE_ACCOUNT_ID, self::FAKE_ACCOUNT_ACCESS_ID); + $this->user->delete(self::FAKE_ACCOUNT_ACCESS_ID); } private function getExpectedData(): array diff --git a/tests/MailtrapGeneralClientTest.php b/tests/MailtrapGeneralClientTest.php index 17c5623..5d5d2d6 100644 --- a/tests/MailtrapGeneralClientTest.php +++ b/tests/MailtrapGeneralClientTest.php @@ -26,8 +26,11 @@ public function getLayerInterfaceClassName(): string public function mapInstancesProvider(): iterable { - foreach (MailtrapGeneralClient::API_MAPPING as $item) { - yield [new $item($this->getConfigMock())]; + foreach (MailtrapGeneralClient::API_MAPPING as $key => $item) { + yield match ($key) { + 'permissions', 'users' => [new $item($this->getConfigMock(), self::FAKE_ACCOUNT_ID)], + default => [new $item($this->getConfigMock())], + }; } } } From 47c607f79cb1cde809d8ed68ca3d53fe3376a605 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Tue, 28 May 2024 19:38:51 +0200 Subject: [PATCH 17/23] add cron for Unit tests workflow --- .github/workflows/ci-phpunit.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci-phpunit.yml b/.github/workflows/ci-phpunit.yml index aa8d875..dec4fc1 100644 --- a/.github/workflows/ci-phpunit.yml +++ b/.github/workflows/ci-phpunit.yml @@ -8,6 +8,8 @@ on: - 'release/**' - 'feature/**' - 'main' + schedule: + - cron: '0 0 * * *' # Runs every day at midnight UTC jobs: phpunit-tests: From 31087bd322da57940f34a127ef7807c37dad1413 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 5 Jun 2024 17:15:15 +0200 Subject: [PATCH 18/23] fix examples --- examples/sending/emails.php | 14 ++++---------- examples/testing/attachments.php | 1 - examples/testing/emails.php | 6 ++---- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/examples/sending/emails.php b/examples/sending/emails.php index 79fa742..b5c133f 100644 --- a/examples/sending/emails.php +++ b/examples/sending/emails.php @@ -24,9 +24,8 @@ * POST https://send.api.mailtrap.io/api/send */ try { - // your API token from here https://mailtrap.io/api-tokens $mailtrap = MailtrapClient::initSendingEmails( - apiKey: getenv('MAILTRAP_API_KEY') + apiKey: getenv('MAILTRAP_API_KEY') #your API token from here https://mailtrap.io/api-tokens ); $email = (new Email()) @@ -87,9 +86,8 @@ * Optional template variables that will be used to generate actual subject, text and html from email template */ try { - // your API token from here https://mailtrap.io/api-tokens $mailtrap = MailtrapClient::initSendingEmails( - apiKey: getenv('MAILTRAP_API_KEY') + apiKey: getenv('MAILTRAP_API_KEY') #your API token from here https://mailtrap.io/api-tokens ); $email = (new Email()) @@ -126,10 +124,8 @@ * POST https://bulk.api.mailtrap.io/api/send */ try { - // your API token from here https://mailtrap.io/api-tokens - $apiKey = getenv('MAILTRAP_API_KEY'); $mailtrap = MailtrapClient::initSendingEmails( - apiKey: getenv('MAILTRAP_API_KEY'), + apiKey: getenv('MAILTRAP_API_KEY'), #your API token from here https://mailtrap.io/api-tokens isBulk: true # Bulk sending (@see https://help.mailtrap.io/article/113-sending-streams) ); @@ -191,10 +187,8 @@ * Optional template variables that will be used to generate actual subject, text and html from email template */ try { - // your API token from here https://mailtrap.io/api-tokens - $apiKey = getenv('MAILTRAP_API_KEY'); $mailtrap = MailtrapClient::initSendingEmails( - apiKey: getenv('MAILTRAP_API_KEY'), + apiKey: getenv('MAILTRAP_API_KEY'), #your API token from here https://mailtrap.io/api-tokens isBulk: true # Bulk sending (@see https://help.mailtrap.io/article/113-sending-streams) ); diff --git a/examples/testing/attachments.php b/examples/testing/attachments.php index 65cea4b..48c4ae1 100644 --- a/examples/testing/attachments.php +++ b/examples/testing/attachments.php @@ -6,7 +6,6 @@ require __DIR__ . '/../vendor/autoload.php'; -// your API token from here https://mailtrap.io/api-tokens $accountId = getenv('MAILTRAP_ACCOUNT_ID'); $inboxId = getenv('MAILTRAP_INBOX_ID'); $config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens diff --git a/examples/testing/emails.php b/examples/testing/emails.php index 5d9dd1e..d7273a1 100644 --- a/examples/testing/emails.php +++ b/examples/testing/emails.php @@ -24,9 +24,8 @@ * POST https://sandbox.api.mailtrap.io/api/send/{inbox_id} */ try { - // your API token from here https://mailtrap.io/api-tokens $mailtrap = MailtrapClient::initSendingEmails( - apiKey: getenv('MAILTRAP_API_KEY'), + apiKey: getenv('MAILTRAP_API_KEY'), #your API token from here https://mailtrap.io/api-tokens isSandbox: true, # Sandbox sending (@see https://help.mailtrap.io/article/109-getting-started-with-mailtrap-email-testing) inboxId: getenv('MAILTRAP_INBOX_ID') # required param for sandbox sending ); @@ -91,9 +90,8 @@ * Optional template variables that will be used to generate actual subject, text and html from email template */ try { - // your API token from here https://mailtrap.io/api-tokens $mailtrap = MailtrapClient::initSendingEmails( - apiKey: getenv('MAILTRAP_API_KEY'), + apiKey: getenv('MAILTRAP_API_KEY'), #your API token from here https://mailtrap.io/api-tokens isSandbox: true, # Sandbox sending (@see https://help.mailtrap.io/article/109-getting-started-with-mailtrap-email-testing) inboxId: getenv('MAILTRAP_INBOX_ID') # required param for sandbox sending ); From 73b161d95bde35e6538a3bf738c2f4fcb0ea1c7d Mon Sep 17 00:00:00 2001 From: gaalferov Date: Thu, 6 Jun 2024 11:55:54 +0200 Subject: [PATCH 19/23] add MailtrapEmail wrapper (MIME) + tests --- CHANGELOG.md | 8 ++ README.md | 50 ++++------ examples/sending/emails.php | 93 +++++++----------- examples/testing/emails.php | 51 ++++------ src/Bridge/Symfony/README.md | 14 ++- src/Mime/MailtrapEmail.php | 75 ++++++++++++++ tests/Api/AbstractEmailsTest.php | 161 +++++++++++++++++++++++++++++++ tests/Api/Sandbox/EmailsTest.php | 55 +++++++++++ 8 files changed, 390 insertions(+), 117 deletions(-) create mode 100644 src/Mime/MailtrapEmail.php diff --git a/CHANGELOG.md b/CHANGELOG.md index ef56be2..706cd4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [2.0.0] - 2024-06-12 +- [BC BREAK] PHP 7.4 will no longer be supported (PHP 8.0+). +- [BC BREAK] Rebuild `Emails` layers to use the `inboxId` at the client level ([examples](examples/testing/emails.php)) +- [BC BREAK] Rebuild SANDBOX `Projects` & `Messages` & `Attachments` & `Inboxes` layers ([examples](examples/testing)) +- [BC BREAK] Rebuild GENERAL `Accounts` & `Permissions` & `Users` layers ([examples](examples/general)) +- Added a short method to get the Email layer depending on config params `MailtrapClient::initSendingEmails()` +- Added MailtrapEmail wrapper (MIME) for easy add category, custom variables, template uuid, etc. + ## [1.9.0] - 2024-05-06 - Support templates in testing diff --git a/README.md b/README.md index 0f7d35b..ae3a400 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,9 @@ Here's how to send a message using the SDK: ```php from(new Address('example@your-domain-here.com', 'Mailtrap Test')) ->replyTo(new Address('reply@your-domain-here.com')) ->to(new Address('email@example.com', 'Jon')) @@ -70,28 +68,22 @@ $email = (new Email()) ' ) ->embed(fopen('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg', 'r'), 'logo', 'image/svg+xml') - ; - - // Headers - $email->getHeaders() + ->category('Integration Test') + ->customVariables([ + 'user_id' => '45982', + 'batch_id' => 'PSJ-12' + ]) +; + +// Custom email headers (optional) +$email->getHeaders() ->addTextHeader('X-Message-Source', 'domain.com') ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')) // the same as addTextHeader - ; - - // Custom Variables - $email->getHeaders() - ->add(new CustomVariableHeader('user_id', '45982')) - ->add(new CustomVariableHeader('batch_id', 'PSJ-12')) - ; - - // Category (should be only one) - $email->getHeaders() - ->add(new CategoryHeader('Integration Test')) - ; - +; + try { $response = $mailtrap->send($email); - + var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; @@ -100,27 +92,27 @@ try { // OR -> Mailtrap BULK SENDING client (real) try { - $mailtrap = MailtrapClient::initSendingEmails( + $mailtrapBulkSending = MailtrapClient::initSendingEmails( apiKey: getenv('MAILTRAP_API_KEY'), # your API token from here https://mailtrap.io/api-tokens isBulk: true # Bulk sending (@see https://help.mailtrap.io/article/113-sending-streams) ); - - $response = $mailtrap->send($email); + + $response = $mailtrapBulkSending->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } -// OR -> Mailtrap SANDBOX client (testing) +// OR -> Mailtrap Testing client (sandbox) try { - $mailtrap = MailtrapClient::initSendingEmails( + $mailtrapTesting = MailtrapClient::initSendingEmails( apiKey: getenv('MAILTRAP_API_KEY'), # your API token from here https://mailtrap.io/api-tokens isSandbox: true, # Sandbox sending (@see https://help.mailtrap.io/article/109-getting-started-with-mailtrap-email-testing) inboxId: getenv('MAILTRAP_INBOX_ID') # required param for sandbox sending ); - - $response = $mailtrap->send($email); + + $response = $mailtrapTesting->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { diff --git a/examples/sending/emails.php b/examples/sending/emails.php index b5c133f..969528f 100644 --- a/examples/sending/emails.php +++ b/examples/sending/emails.php @@ -1,11 +1,8 @@ from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) ->replyTo(new Address('reply@YOUR-DOMAIN-HERE.com')) ->to(new Address('email@example.com', 'Jon')) @@ -50,25 +47,19 @@ ) ->embed(fopen('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg', 'r'), 'logo', 'image/svg+xml') ->attachFromPath('README.md') + ->customVariables([ + 'user_id' => '45982', + 'batch_id' => 'PSJ-12' + ]) + ->category('Integration Test') ; - // Headers + // Custom email headers (optional) $email->getHeaders() - ->addTextHeader('X-Message-Source', '1alf.com') + ->addTextHeader('X-Message-Source', 'test.com') ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')) ; - // Custom Variables - $email->getHeaders() - ->add(new CustomVariableHeader('user_id', '45982')) - ->add(new CustomVariableHeader('batch_id', 'PSJ-12')) - ; - - // Category (should be only one) - $email->getHeaders() - ->add(new CategoryHeader('Integration Test')) - ; - $response = $mailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) @@ -90,19 +81,17 @@ apiKey: getenv('MAILTRAP_API_KEY') #your API token from here https://mailtrap.io/api-tokens ); - $email = (new Email()) + $email = (new MailtrapEmail()) ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) ->replyTo(new Address('reply@YOUR-DOMAIN-HERE.com')) ->to(new Address('example@gmail.com', 'Jon')) - ; - - // Template UUID and Variables - $email->getHeaders() - ->add(new TemplateUuidHeader('bfa432fd-0000-0000-0000-8493da283a69')) - ->add(new TemplateVariableHeader('user_name', 'Jon Bush')) - ->add(new TemplateVariableHeader('next_step_link', 'https://mailtrap.io/')) - ->add(new TemplateVariableHeader('get_started_link', 'https://mailtrap.io/')) - ->add(new TemplateVariableHeader('onboarding_video_link', 'some_video_link')) + ->templateUuid('bfa432fd-0000-0000-0000-8493da283a69') + ->templateVariables([ + 'user_name' => 'Jon Bush', + 'next_step_link' => 'https://mailtrap.io/', + 'get_started_link' => 'https://mailtrap.io/', + 'onboarding_video_link' => 'some_video_link' + ]) ; $response = $mailtrap->send($email); @@ -124,12 +113,12 @@ * POST https://bulk.api.mailtrap.io/api/send */ try { - $mailtrap = MailtrapClient::initSendingEmails( + $bulkMailtrap = MailtrapClient::initSendingEmails( apiKey: getenv('MAILTRAP_API_KEY'), #your API token from here https://mailtrap.io/api-tokens isBulk: true # Bulk sending (@see https://help.mailtrap.io/article/113-sending-streams) ); - $email = (new Email()) + $email = (new MailtrapEmail()) ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) ->replyTo(new Address('reply@YOUR-DOMAIN-HERE.com')) ->to(new Address('email@example.com', 'Jon')) @@ -151,26 +140,20 @@ ) ->embed(fopen('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg', 'r'), 'logo', 'image/svg+xml') ->attachFromPath('README.md') + ->customVariables([ + 'user_id' => '45982', + 'batch_id' => 'PSJ-12' + ]) + ->category('Integration Test') ; - // Headers + // Custom email headers (optional) $email->getHeaders() - ->addTextHeader('X-Message-Source', '1alf.com') + ->addTextHeader('X-Message-Source', 'test.com') ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')) ; - // Custom Variables - $email->getHeaders() - ->add(new CustomVariableHeader('user_id', '45982')) - ->add(new CustomVariableHeader('batch_id', 'PSJ-12')) - ; - - // Category (should be only one) - $email->getHeaders() - ->add(new CategoryHeader('Integration Test')) - ; - - $response = $mailtrap->send($email); + $response = $bulkMailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { @@ -187,27 +170,25 @@ * Optional template variables that will be used to generate actual subject, text and html from email template */ try { - $mailtrap = MailtrapClient::initSendingEmails( + $bulkMailtrap = MailtrapClient::initSendingEmails( apiKey: getenv('MAILTRAP_API_KEY'), #your API token from here https://mailtrap.io/api-tokens isBulk: true # Bulk sending (@see https://help.mailtrap.io/article/113-sending-streams) ); - $email = (new Email()) + $email = (new MailtrapEmail()) ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) ->replyTo(new Address('reply@YOUR-DOMAIN-HERE.com')) ->to(new Address('example@gmail.com', 'Jon')) + ->templateUuid('bfa432fd-0000-0000-0000-8493da283a69') + ->templateVariables([ + 'user_name' => 'Jon Bush', + 'next_step_link' => 'https://mailtrap.io/', + 'get_started_link' => 'https://mailtrap.io/', + 'onboarding_video_link' => 'some_video_link' + ]) ; - // Template UUID and Variables - $email->getHeaders() - ->add(new TemplateUuidHeader('bfa432fd-0000-0000-0000-8493da283a69')) - ->add(new TemplateVariableHeader('user_name', 'Jon Bush')) - ->add(new TemplateVariableHeader('next_step_link', 'https://mailtrap.io/')) - ->add(new TemplateVariableHeader('get_started_link', 'https://mailtrap.io/')) - ->add(new TemplateVariableHeader('onboarding_video_link', 'some_video_link')) - ; - - $response = $mailtrap->send($email); + $response = $bulkMailtrap->send($email); var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { diff --git a/examples/testing/emails.php b/examples/testing/emails.php index d7273a1..8d7d1f2 100644 --- a/examples/testing/emails.php +++ b/examples/testing/emails.php @@ -1,13 +1,9 @@ from(new Address('mailtrap@example.com', 'Mailtrap Test')) + $email = (new MailtrapEmail()) + ->from(new Address('mailtrap@example.com', 'Mailtrap Test')) // <--- you should use the domain which is linked to template UUID (otherwise you will get 401) ->replyTo(new Address('reply@example.com')) ->to(new Address('email@example.com', 'Jon')) ->cc('mailtrapqa@example.com') @@ -51,25 +47,19 @@ ) ->embed(fopen('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg', 'r'), 'logo', 'image/svg+xml') ->attachFromPath('README.md') + ->customVariables([ + 'user_id' => '45982', + 'batch_id' => 'PSJ-12' + ]) + ->category('Integration Test') ; - // Headers + // Custom email headers (optional) $email->getHeaders() - ->addTextHeader('X-Message-Source', '1alf.com') + ->addTextHeader('X-Message-Source', 'test.com') ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')) ; - // Custom Variables - $email->getHeaders() - ->add(new CustomVariableHeader('user_id', '45982')) - ->add(new CustomVariableHeader('batch_id', 'PSJ-12')) - ; - - // Category (should be only one) - $email->getHeaders() - ->add(new CategoryHeader('Integration Test')) - ; - $response = $mailtrap->send($email); // print all possible information from the response @@ -96,23 +86,24 @@ inboxId: getenv('MAILTRAP_INBOX_ID') # required param for sandbox sending ); - $email = (new Email()) + $email = (new MailtrapEmail()) ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use the domain which is linked to template UUID (otherwise you will get 401) ->replyTo(new Address('reply@YOUR-DOMAIN-HERE.com')) ->to(new Address('example@gmail.com', 'Jon')) - ; - - // Template UUID and Variables - $email->getHeaders() - ->add(new TemplateUuidHeader('bfa432fd-0000-0000-0000-8493da283a69')) - ->add(new TemplateVariableHeader('user_name', 'Jon Bush')) - ->add(new TemplateVariableHeader('next_step_link', 'https://mailtrap.io/')) - ->add(new TemplateVariableHeader('get_started_link', 'https://mailtrap.io/')) - ->add(new TemplateVariableHeader('onboarding_video_link', 'some_video_link')) + ->templateUuid('bfa432fd-0000-0000-0000-8493da283a69') + ->templateVariables([ + 'user_name' => 'Jon Bush', + 'next_step_link' => 'https://mailtrap.io/', + 'get_started_link' => 'https://mailtrap.io/', + 'onboarding_video_link' => 'some_video_link' + ]) ; $response = $mailtrap->send($email); + // print all possible information from the response + var_dump($response->getHeaders()); //headers (array) + var_dump($response->getStatusCode()); //status code (int) var_dump(ResponseHelper::toArray($response)); // body (array) } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; diff --git a/src/Bridge/Symfony/README.md b/src/Bridge/Symfony/README.md index caf8769..dbbbba6 100644 --- a/src/Bridge/Symfony/README.md +++ b/src/Bridge/Symfony/README.md @@ -58,6 +58,7 @@ php bin/console mailer:test to@example.com ```php to('to@xample.com') + $message = (new MailtrapEmail()) ->from('from@xample.com') + ->to('to@xample.com') + //->cc('cc@example.com') + //->bcc('bcc@example.com') + //->replyTo('fabien@example.com') + //->priority(Email::PRIORITY_HIGH) ->subject('Test email') ->text('text') + ->category('category') + ->customVariables([ + 'var1' => 'value1', + 'var2' => 'value2' + ]) ; $response = $this->transport->send($message); diff --git a/src/Mime/MailtrapEmail.php b/src/Mime/MailtrapEmail.php new file mode 100644 index 0000000..82b8873 --- /dev/null +++ b/src/Mime/MailtrapEmail.php @@ -0,0 +1,75 @@ +getHeaders()->has(TemplateUuidHeader::VAR_NAME)) { + $this->getHeaders()->remove(TemplateUuidHeader::VAR_NAME); + } + + $this->getHeaders()->add(new TemplateUuidHeader($templateUuid)); + + return $this; + } + + public function templateVariable(string $name, string $value): self + { + $this->getHeaders()->add(new TemplateVariableHeader($name, $value)); + + return $this; + } + + public function templateVariables(array $variables): self + { + foreach ($variables as $name => $value) { + $this->templateVariable($name, $value); + } + + return $this; + } + + public function category(string $category): self + { + // Only one category is allowed + if ($this->getHeaders()->has(CategoryHeader::VAR_NAME)) { + $this->getHeaders()->remove(CategoryHeader::VAR_NAME); + } + + $this->getHeaders()->add(new CategoryHeader($category)); + + return $this; + } + + public function customVariable(string $name, string $value): self + { + $this->getHeaders()->add(new CustomVariableHeader($name, $value)); + + return $this; + } + + public function customVariables(array $variables): self + { + foreach ($variables as $name => $value) { + $this->customVariable($name, $value); + } + + return $this; + } +} diff --git a/tests/Api/AbstractEmailsTest.php b/tests/Api/AbstractEmailsTest.php index 507f3c2..01f9223 100644 --- a/tests/Api/AbstractEmailsTest.php +++ b/tests/Api/AbstractEmailsTest.php @@ -14,6 +14,7 @@ use Mailtrap\Exception\HttpClientException; use Mailtrap\Exception\RuntimeException; use Mailtrap\Helper\ResponseHelper; +use Mailtrap\Mime\MailtrapEmail; use Mailtrap\Tests\MailtrapTestCase; use Nyholm\Psr7\Response; use Symfony\Component\Mime\Address; @@ -187,6 +188,60 @@ public function testValidSendTemplate(): void $this->assertArrayHasKey('message_ids', $responseData); } + public function testValidSendTemplateNewEmailWrapper(): void + { + $expectedData = [ + "success" => true, + "message_ids" => [ + "0c7fd939-02cf-11ed-88c2-0a58a9feac02" + ] + ]; + + $email = (new MailtrapEmail()) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->to(new Address('bar@example.com', 'Mr. Recipient')) + ->templateUuid('bfa432fd-0000-0000-0000-8493da283a69') + ->templateVariables([ + 'user_name' => 'Jon Bush', + 'unicode_user_name' => 'Subašić', + 'next_step_link' => 'https://mailtrap.io/', + 'get_started_link' => 'https://mailtrap.io/', + 'onboarding_video_link' => 'some_video_link' + ]) + ; + + $this->email + ->expects($this->once()) + ->method('httpPost') + ->with($this->getHost() . '/api/send', [], [ + 'from' => [ + 'email' => 'foo@example.com', + 'name' => 'Ms. Foo Bar', + ], + 'to' => [[ + 'email' => 'bar@example.com', + 'name' => 'Mr. Recipient', + ]], + 'template_uuid' => 'bfa432fd-0000-0000-0000-8493da283a69', + 'template_variables' => [ + 'user_name' => 'Jon Bush', + 'unicode_user_name' => 'Subašić', // should not be encoded as it is not a real header + 'next_step_link' => 'https://mailtrap.io/', + 'get_started_link' => 'https://mailtrap.io/', + 'onboarding_video_link' => 'some_video_link', + ] + ]) + ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); + + $response = $this->email->send($email); + $responseData = ResponseHelper::toArray($response); + + $this->assertInstanceOf(Response::class, $response); + $this->assertCount(2, $responseData); + $this->assertArrayHasKey('success', $responseData); + $this->assertArrayHasKey('message_ids', $responseData); + } + public function testAttachments(): void { $email = (new Email()) @@ -242,6 +297,25 @@ public function testCustomVariables($name, $value): void $this->assertEquals($value, $payload[CustomVariableHeader::VAR_NAME][$name]); } + /** + * @dataProvider validCustomVariablesDataProvider + */ + public function testCustomVariablesNewEmailWrapper($name, $value): void + { + $email = (new MailtrapEmail()) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->customVariable($name, $value) + ; + + $method = new \ReflectionMethod(Emails::class, 'getPayload'); + $method->setAccessible(true); + $payload = $method->invoke(new Emails($this->getConfigMock()), $email); + + $this->assertArrayHasKey(CustomVariableHeader::VAR_NAME, $payload); + $this->assertArrayHasKey($name, $payload[CustomVariableHeader::VAR_NAME]); + $this->assertEquals($value, $payload[CustomVariableHeader::VAR_NAME][$name]); + } + /** * @dataProvider validEmailCategoryDataProvider */ @@ -259,6 +333,40 @@ public function testEmailCategory($value): void $this->assertEquals($value, $payload[CategoryHeader::VAR_NAME]); } + /** + * @dataProvider validEmailCategoryDataProvider + */ + public function testEmailCategoryNewEmailWrapper($value): void + { + $email = (new MailtrapEmail()) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->category($value) + ; + + $method = new \ReflectionMethod(Emails::class, 'getPayload'); + $method->setAccessible(true); + $payload = $method->invoke(new Emails($this->getConfigMock()), $email); + + $this->assertArrayHasKey(CategoryHeader::VAR_NAME, $payload); + $this->assertEquals($value, $payload[CategoryHeader::VAR_NAME]); + } + + public function testValidCountOfEmailCategoryNewEmailWrapper(): void + { + $email = (new MailtrapEmail()) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->category('category 1') + ->category('category 2') // will be overridden + ; + + $method = new \ReflectionMethod(Emails::class, 'getPayload'); + $method->setAccessible(true); + $payload = $method->invoke(new Emails($this->getConfigMock()), $email); + + $this->assertArrayHasKey(CategoryHeader::VAR_NAME, $payload); + $this->assertEquals('category 2', $payload[CategoryHeader::VAR_NAME]); + } + public function testInvalidCountOfEmailCategory(): void { $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); @@ -295,6 +403,40 @@ public function testTemplateUuid($value): void $this->assertEquals($value, $payload[TemplateUuidHeader::VAR_NAME]); } + /** + * @dataProvider validTemplateUuidDataProvider + */ + public function testTemplateUuidNewEmailWrapper($value): void + { + $email = (new MailtrapEmail()) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->templateUuid($value) + ; + + $method = new \ReflectionMethod(Emails::class, 'getPayload'); + $method->setAccessible(true); + $payload = $method->invoke(new Emails($this->getConfigMock()), $email); + + $this->assertArrayHasKey(TemplateUuidHeader::VAR_NAME, $payload); + $this->assertEquals($value, $payload[TemplateUuidHeader::VAR_NAME]); + } + + public function testValidCountOfTemplateUuidNewEmailWrapper(): void + { + $email = (new MailtrapEmail()) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->templateUuid('11111111-0000-0000-0000-8493da283a69') + ->templateUuid('22222222-0000-0000-0000-8493da283a69') // will be overridden + ; + + $method = new \ReflectionMethod(Emails::class, 'getPayload'); + $method->setAccessible(true); + $payload = $method->invoke(new Emails($this->getConfigMock()), $email); + + $this->assertArrayHasKey(TemplateUuidHeader::VAR_NAME, $payload); + $this->assertEquals('22222222-0000-0000-0000-8493da283a69', $payload[TemplateUuidHeader::VAR_NAME]); + } + public function testInvalidCountOfTemplateUuid(): void { $email = (new Email())->from(new Address('foo@example.com', 'Ms. Foo Bar')); @@ -332,6 +474,25 @@ public function testTemplateVariables($name, $value): void $this->assertEquals($value, $payload[TemplateVariableHeader::VAR_NAME][$name]); } + /** + * @dataProvider validTemplateVariablesDataProvider + */ + public function testTemplateVariablesNewEmailWrapper($name, $value): void + { + $email = (new MailtrapEmail()) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->templateVariable($name, $value) + ; + + $method = new \ReflectionMethod(Emails::class, 'getPayload'); + $method->setAccessible(true); + $payload = $method->invoke(new Emails($this->getConfigMock()), $email); + + $this->assertArrayHasKey(TemplateVariableHeader::VAR_NAME, $payload); + $this->assertArrayHasKey($name, $payload[TemplateVariableHeader::VAR_NAME]); + $this->assertEquals($value, $payload[TemplateVariableHeader::VAR_NAME][$name]); + } + // public function validHeadersDataProvider(): array diff --git a/tests/Api/Sandbox/EmailsTest.php b/tests/Api/Sandbox/EmailsTest.php index baf54fa..a4404d5 100644 --- a/tests/Api/Sandbox/EmailsTest.php +++ b/tests/Api/Sandbox/EmailsTest.php @@ -9,6 +9,7 @@ use Mailtrap\EmailHeader\Template\TemplateUuidHeader; use Mailtrap\EmailHeader\Template\TemplateVariableHeader; use Mailtrap\Helper\ResponseHelper; +use Mailtrap\Mime\MailtrapEmail; use Mailtrap\Tests\MailtrapTestCase; use Nyholm\Psr7\Response; use Symfony\Component\Mime\Address; @@ -155,4 +156,58 @@ public function testValidSendTemplateToSandbox(): void $this->assertArrayHasKey('success', $responseData); $this->assertArrayHasKey('message_ids', $responseData); } + + public function testValidSendTemplateToSandboxNewEmailWrapper(): void + { + $expectedData = [ + "success" => true, + "message_ids" => [ + "0c7fd939-02cf-11ed-88c2-0a58a9feac02" + ] + ]; + + $email = (new MailtrapEmail()) + ->from(new Address('foo@example.com', 'Ms. Foo Bar')) + ->to(new Address('bar@example.com', 'Mr. Recipient')) + ->templateUuid('bfa432fd-0000-0000-0000-8493da283a69') + ->templateVariables([ + 'user_name' => 'Jon Bush', + 'unicode_user_name' => 'Subašić', // should not be encoded as it is not a real header + 'next_step_link' => 'https://mailtrap.io/', + 'get_started_link' => 'https://mailtrap.io/', + 'onboarding_video_link' => 'some_video_link', + ]) + ; + + $this->email + ->expects($this->once()) + ->method('httpPost') + ->with(AbstractApi::SENDMAIL_SANDBOX_HOST . '/api/send/' . self::FAKE_INBOX_ID, [], [ + 'from' => [ + 'email' => 'foo@example.com', + 'name' => 'Ms. Foo Bar', + ], + 'to' => [[ + 'email' => 'bar@example.com', + 'name' => 'Mr. Recipient', + ]], + 'template_uuid' => 'bfa432fd-0000-0000-0000-8493da283a69', + 'template_variables' => [ + 'user_name' => 'Jon Bush', + 'unicode_user_name' => 'Subašić', // should not be encoded as it is not a real header + 'next_step_link' => 'https://mailtrap.io/', + 'get_started_link' => 'https://mailtrap.io/', + 'onboarding_video_link' => 'some_video_link', + ] + ]) + ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedData))); + + $response = $this->email->send($email); + $responseData = ResponseHelper::toArray($response); + + $this->assertInstanceOf(Response::class, $response); + $this->assertCount(2, $responseData); + $this->assertArrayHasKey('success', $responseData); + $this->assertArrayHasKey('message_ids', $responseData); + } } From 3e1ed55d099e03ffbec5fcde24fcdbbcbe047e92 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Thu, 20 Jun 2024 14:28:55 +0200 Subject: [PATCH 20/23] add UPGRADE to version 2.x instruction --- UPGRADE-2.0.md | 128 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 UPGRADE-2.0.md diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md new file mode 100644 index 0000000..8483f9d --- /dev/null +++ b/UPGRADE-2.0.md @@ -0,0 +1,128 @@ +UPGRADE FROM 1.x to 2.0 +======================= + +### Email Layers +* Added a short method to get one of the Email layers (Sending/Bulk/Sandbox) depending on config params `MailtrapClient::initSendingEmails()` + * string $apiKey + * bool $isBulk = false + * bool $isSandbox = false + * int $inboxId = null +* **BC BREAK**: In Sandbox layer `inboxId` should be passed at the client level. + + __Before__: + ```php + $mailtrap = new MailtrapClient(new Config(getenv('MAILTRAP_API_KEY'))); + + $response = $mailtrap + ->sandbox() + ->emails() + ->send($email, 1000001); # <--- inboxId here + ``` + __After__: + ```php + # short method using `initSendingEmails` + $mailtrap = MailtrapClient::initSendingEmails( + apiKey: getenv('MAILTRAP_API_KEY'), #your API token from here https://mailtrap.io/api-tokens + isSandbox: true, # required param for sandbox sending + inboxId: getenv('MAILTRAP_INBOX_ID') # <--- inboxId here + ); + + # or using the client directly (old variant) + $mailtrap = (new MailtrapClient(new Config(getenv('MAILTRAP_API_KEY')))) + ->sandbox() + ->emails(getenv('MAILTRAP_INBOX_ID')); # <--- inboxId here + + $response = $mailtrap->send($email); + ``` + +### General API +* **BC BREAK**: Rebuild `Accounts` & `Permissions` & `Users` layers ([examples](examples/general)) + + __Before__: + ```php + $mailtrap = new MailtrapClient(new Config(getenv('MAILTRAP_API_KEY'))); # no changes here + + $response = $mailtrap + ->general() + ->permissions() + ->getResources(getenv('MAILTRAP_ACCOUNT_ID')); # <--- accountId here + + $response = $mailtrap + ->general() + ->users() + ->getList(getenv('MAILTRAP_ACCOUNT_ID')); # <--- accountId here + ``` + __After__: + ```php + // all permissions endpoints + $response = $mailtrap + ->general() + ->permissions(getenv('MAILTRAP_ACCOUNT_ID')) # <--- accountId here + ->getResources(); + + // all users endpoints + $response = $mailtrap + ->general() + ->users(getenv('MAILTRAP_ACCOUNT_ID')) # <--- accountId here + ->getList(); + ``` + +### Sandbox API +* **BC BREAK**: Rebuild `Projects` & `Messages` & `Attachments` & `Inboxes` layers ([examples](examples/testing)) + + __Before__: + ```php + $mailtrap = new MailtrapClient(new Config(getenv('MAILTRAP_API_KEY'))); # no changes here + + $response = $mailtrap + ->sandbox() + ->inboxes() + ->getList(getenv('MAILTRAP_ACCOUNT_ID')); # <--- accountId here + ``` + __After__: + ```php + // all sandbox(testing) endpoints: projects, messages, attachments, inboxes + $response = $mailtrap + ->sandbox() + ->inboxes(getenv('MAILTRAP_ACCOUNT_ID')) # <--- accountId here + ->getList(); + ``` + +### Email Template class +* Added `MailtrapEmail` wrapper (MIME) for easy use category, custom variables, template uuid, etc. + + __Before__: + ```php + $email = (new Email()) + ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) + ->replyTo(new Address('reply@YOUR-DOMAIN-HERE.com')) + ->to(new Address('example@gmail.com', 'Jon')) + ; + + // Template UUID and Variables + $email->getHeaders() + ->add(new TemplateUuidHeader('bfa432fd-0000-0000-0000-8493da283a69')) + ->add(new TemplateVariableHeader('user_name', 'Jon Bush')) + ->add(new TemplateVariableHeader('next_step_link', 'https://mailtrap.io/')) + ->add(new TemplateVariableHeader('get_started_link', 'https://mailtrap.io/')) + ->add(new TemplateVariableHeader('onboarding_video_link', 'some_video_link')) + ; + ``` + + __After__: + ```php + use Mailtrap\Mime\MailtrapEmail; + + $email = (new MailtrapEmail()) # <--- new MIME class with template support + ->from(new Address('example@YOUR-DOMAIN-HERE.com', 'Mailtrap Test')) // <--- you should use your domain here that you installed in the mailtrap.io admin area (otherwise you will get 401) + ->replyTo(new Address('reply@YOUR-DOMAIN-HERE.com')) + ->to(new Address('example@gmail.com', 'Jon')) + ->templateUuid('bfa432fd-0000-0000-0000-8493da283a69') + ->templateVariables([ + 'user_name' => 'Jon Bush', + 'next_step_link' => 'https://mailtrap.io/', + 'get_started_link' => 'https://mailtrap.io/', + 'onboarding_video_link' => 'some_video_link' + ]) + ; + ``` From 1b5549a693c7454175183d3cbbedcd243d8e7b97 Mon Sep 17 00:00:00 2001 From: gaalferov Date: Wed, 3 Jul 2024 17:24:04 +0200 Subject: [PATCH 21/23] uncomment example in README --- src/Bridge/Symfony/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bridge/Symfony/README.md b/src/Bridge/Symfony/README.md index dbbbba6..1a5c54a 100644 --- a/src/Bridge/Symfony/README.md +++ b/src/Bridge/Symfony/README.md @@ -85,10 +85,10 @@ final class SomeController extends AbstractController $message = (new MailtrapEmail()) ->from('from@xample.com') ->to('to@xample.com') - //->cc('cc@example.com') - //->bcc('bcc@example.com') - //->replyTo('fabien@example.com') - //->priority(Email::PRIORITY_HIGH) + ->cc('cc@example.com') + ->bcc('bcc@example.com') + ->replyTo('fabien@example.com') + ->priority(Email::PRIORITY_HIGH) ->subject('Test email') ->text('text') ->category('category') From 0a9acf36c7eb2f8c3821091d6eac2e4f29575198 Mon Sep 17 00:00:00 2001 From: Hennadii Alforov Date: Fri, 5 Jul 2024 09:52:29 +0200 Subject: [PATCH 22/23] Update README.md Co-authored-by: Ihor Dobryn --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae3a400..11a77fa 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ use Symfony\Component\Mime\Header\UnstructuredHeader; require __DIR__ . '/vendor/autoload.php'; -// Mailtrap SENDING client (real) +// Mailtrap SENDING client (real) for transactional emails $mailtrap = MailtrapClient::initSendingEmails( apiKey: getenv('MAILTRAP_API_KEY') # your API token from here https://mailtrap.io/api-tokens ); From b159619700e2beadb83a175082a37b996f4fe8c0 Mon Sep 17 00:00:00 2001 From: Hennadii Alforov Date: Fri, 5 Jul 2024 09:52:49 +0200 Subject: [PATCH 23/23] Update examples/testing/messages.php Co-authored-by: Marcin Klocek --- examples/testing/messages.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/testing/messages.php b/examples/testing/messages.php index 72fc609..8a04ba2 100644 --- a/examples/testing/messages.php +++ b/examples/testing/messages.php @@ -11,7 +11,7 @@ $inboxId = getenv('MAILTRAP_INBOX_ID'); $config = new Config(getenv('MAILTRAP_API_KEY')); #your API token from here https://mailtrap.io/api-tokens -$sandboxMessages = (new MailtrapSandboxClient($config))->messages($accountId, $inboxId); #required parameters are accountId amd inboxId +$sandboxMessages = (new MailtrapSandboxClient($config))->messages($accountId, $inboxId); #required parameters are accountId and inboxId /** * Get messages