From 17416dd0aaa992b08ae19b3574002f226d55950f Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 17 Jul 2023 08:06:11 +0200 Subject: [PATCH 1/7] Change package vendor In order to clearly state saccas takes over the maintenance for this unmaintained software. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 91971b6..77a3758 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "ericmartel/codeception-email-mailhog", + "name": "saccas/codeception-email-mailhog", "description": "Provides test helpers for Codeception when testing email functionality with MailHog", "license": "MIT", "authors": [ From 7354f86437c02ed4b8deaf1f78e930d28893183a Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 17 Jul 2023 08:09:59 +0200 Subject: [PATCH 2/7] Inline code from codeception-mail package There seems to be no need to split this up. There is not a wide adoption of other packages using the same API. Furthermore an interface would be better suited. Merging both makes maintenance easier. --- src/MailHog.php | 4 +- src/TestsEmails.php | 581 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 582 insertions(+), 3 deletions(-) create mode 100644 src/TestsEmails.php diff --git a/src/MailHog.php b/src/MailHog.php index a97185a..1681a58 100644 --- a/src/MailHog.php +++ b/src/MailHog.php @@ -15,9 +15,7 @@ class MailHog extends Module { - use \Codeception\Email\TestsEmails; - - use \Codeception\Email\EmailServiceProvider; + use TestsEmails; /** * HTTP Client to interact with MailHog diff --git a/src/TestsEmails.php b/src/TestsEmails.php new file mode 100644 index 0000000..6c41690 --- /dev/null +++ b/src/TestsEmails.php @@ -0,0 +1,581 @@ +getCurrentInbox(); + $this->assertGreaterThan(0, count($currentInbox)); + } + + /** + * Have Number Of Emails + * + * Checks that the amount of emails in the inbox is exactly $expected + * @params int $expected Number of expected emails + */ + public function haveNumberOfEmails($expected) + { + $currentInbox = $this->getCurrentInbox(); + $this->assertEquals($expected, count($currentInbox)); + } + + /** + * Dont Have Emails + * + * Checks that there are no emails in the inbox + */ + public function dontHaveEmails() + { + $currentInbox = $this->getCurrentInbox(); + $this->assertEquals(0, count($currentInbox)); + } + + /** + * Have Unread Emails + * + * Checks that there is at least one unread email + **/ + public function haveUnreadEmails() + { + $unreadInbox = $this->getUnreadInbox(); + $this->assertGreaterThan(0, count($unreadInbox)); + } + + /** + * Have Number Of Unread Emails + * + * Checks that the amount of emails in the unread inbox is exactly $expected + * @params int $expected Number of expected emails + */ + public function haveNumberOfUnreadEmails($expected) + { + $unreadInbox = $this->getUnreadInbox(); + $this->assertEquals($expected, count($unreadInbox)); + } + + /** + * Dont Have Unread Emails + * + * Checks that there are no unread emails in the inbox + */ + public function dontHaveUnreadEmails() + { + $unreadInbox = $this->getUnreadInbox(); + $this->assertEquals(0, count($unreadInbox)); + } + + /** + * See In Opened Email Body + * + * Validates that $expected can be found in the opened email body + * + * @param string $expected Text + */ + public function seeInOpenedEmailBody($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailBody($email, $expected); + } + + /** + * See In Opened Email Subject + * + * Validates that $expected can be found in the opened email subject + * + * @param string $expected Text + */ + public function seeInOpenedEmailSubject($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailSubject($email, $expected); + } + + /** + * Dont See In Opened Email Body + * + * Checks that $expected cannot be found in the opened email body + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailBody($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailBody($email, $expected); + } + + /** + * Dont See In Opened Email Subject + * + * Checks that $expected cannot be found in the opened email subject + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailSubject($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailSubject($email, $expected); + } + + /** + * See In Email Body + * + * Checks that the body of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailBody($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailBody($email), "Email Body Contains"); + } + + /** + * Dont See In Email Body + * + * Checks that the body of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailBody($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailBody($email), "Email Body Doesn't Contain"); + } + + /** + * See In Email Subject + * + * Checks that the subject of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailSubject($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailSubject($email), "Email Subject Contains"); + } + + /** + * Dont See In Email Subject + * + * Checks that the subject of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailSubject($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailSubject($email), "Email Subject Doesn't Contain"); + } + + /** + * See In Opened Email Sender + * + * Checks if the sender of the opened email contains $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailSender($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailSender($email, $expected); + } + + /** + * Dont See In Opened Email Sender + * + * Checks if the sender of the opened email does not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailSender($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailSender($email, $expected); + } + + /** + * See In Email Sender + * + * Checks if the sender of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailSender($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailSender($email)); + } + + /** + * Dont See In Email Sender + * + * Checks if the sender of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailSender($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailSender($email)); + } + + /** + * See In Opened Email Reply To + * + * Checks if the ReplyTo of the opened email contains $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailReplyTo($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailReplyTo($email, $expected); + } + + /** + * Dont See In Opened Email Reply To + * + * Checks if the ReplyTo of the opened email does not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailReplyTo($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailReplyTo($email, $expected); + } + + /** + * See In Email Reply To + * + * Checks if the ReplyTo of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailReplyTo($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailReplyTo($email)); + } + + /** + * Dont See In Email Reply To + * + * Checks if the ReplyTo of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailReplyTo($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailReplyTo($email)); + } + + /** + * See In Opened Email Recipients + * + * Checks that the recipients of the opened email contain $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailRecipients($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailRecipients($email, $expected); + } + + /** + * Dont See In Opened Email Recipients + * + * Checks that the recipients of the opened email do not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailRecipients($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailRecipients($email, $expected); + } + + /** + * See In Email Recipients + * + * Checks that the recipients of $email contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailRecipients($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailRecipients($email)); + } + + /** + * Dont See In Email Recipients + * + * Checks that the recipients of $email do not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailRecipients($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailRecipients($email)); + } + + /** + * See In Opened Email To Field + * + * Checks that the To field of the opened email contains $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailToField($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailToField($email, $expected); + } + + /** + * Dont See In Opened Email To Field + * + * Checks that the To field of the opened email does not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailToField($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailToField($email, $expected); + } + + /** + * See In Email To Field + * + * Checks that the To field of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailToField($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailTo($email)); + } + + /** + * Dont See In Email To Field + * + * Checks that the To field of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailToField($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailTo($email)); + } + + /** + * See In Opened Email CC Field + * + * Checks that the CC field of the opened email contains $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailCCField($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailCCField($email, $expected); + } + + /** + * Dont See In Opened Email CC Field + * + * Checks that the CC field of the opened email does not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailCCField($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailCCField($email, $expected); + } + + /** + * See In Email CC Field + * + * Checks that the CC field of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailCCField($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailCC($email)); + } + + /** + * Dont See In Email CC Field + * + * Checks that the CC field of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailCCField($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailCC($email)); + } + + /** + * See In Opened Email BCC Field + * + * Checks that the BCC field of the opened email contains $expected + * + * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. + * + * @param string $expected Text + */ + public function seeInOpenedEmailBCCField($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailBCCField($email, $expected); + } + + /** + * Dont See In Opened Email BCC Field + * + * Checks that the BCC field of the opened email does not contain $expected + * + * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailBCCField($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailBCCField($email, $expected); + } + + /** + * See In Email BCC Field + * + * Checks that the BCC field of $email contains $expected + * + * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailBCCField($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailBCC($email)); + } + + /** + * Dont See In Email BCC Field + * + * Checks that the BCC field of $email does not contain $expected + * + * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailBCCField($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailBCC($email)); + } + + /** + * See In Opened Email Priority + * + * Checks that the priority of the opened email contains $expected + * + * @param string $expected priority + */ + public function seeInOpenedEmailPriority($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailPriority($email, $expected); + } + + /** + * Dont See In Opened Email Priority + * + * Checks that the priority of the opened email does not contain $expected + * + * @param string $expected priority + */ + public function dontSeeInOpenedEmailPriority($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailPriority($email, $expected); + } + + /** + * See In Email Priority + * + * Checks that the priority of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected priority + */ + public function seeInEmailPriority($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailPriority($email)); + } + + /** + * Dont See In Email Priority + * + * Checks that the priority of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected priority + */ + public function dontSeeInEmailPriority($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailPriority($email)); + } + + /** + + * @param string $content_type_alternative MIME-part Content-Type + * @return string Body + */ + public function grabBodyFromEmail($content_type_alternative = null) + { + $email = $this->getOpenedEmail(); + + if( isset($content_type_alternative) ) { + foreach ($email->MIME->Parts as $part) { + if (!empty($part->Headers->{'Content-Type'}[0]) && + strpos($part->Headers->{'Content-Type'}[0], $content_type_alternative) !== false) { + return $this->getDecodedEmailProperty($part, $part->Body); //return first entry + } + } + return null; //not found + } + return $this->getDecodedEmailProperty($email, $email->Content->Body); //return full email + } +}; From 48b58ca5e9790aef52683b36913cc6a8321f6f6b Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 17 Jul 2023 08:11:10 +0200 Subject: [PATCH 3/7] Ignore generated files from git --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c8153b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/composer.lock +/vendor/ From e5debc7429937693f2ca8862d192af7427e41128 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 17 Jul 2023 08:13:05 +0200 Subject: [PATCH 4/7] Apply a CGL --- .php-cs-fixer.php | 64 +++ composer.json | 3 + src/MailHog.php | 790 ++++++++++++++++--------------- src/TestsEmails.php | 1091 +++++++++++++++++++++---------------------- 4 files changed, 1001 insertions(+), 947 deletions(-) create mode 100644 .php-cs-fixer.php diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..e4cb637 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,64 @@ +in([ + __DIR__ . '/src/', + ]) +; + +$config = new PhpCsFixer\Config(); +return $config + ->setRiskyAllowed(true) + ->setRules([ + '@DoctrineAnnotation' => true, + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'blank_line_after_opening_tag' => true, + 'braces' => ['allow_single_line_closure' => true], + 'cast_spaces' => ['space' => 'none'], + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'dir_constant' => true, + 'function_typehint_space' => true, + 'single_line_comment_style' => ['comment_types' => ['hash']], + 'lowercase_cast' => true, + 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], + 'modernize_types_casting' => true, + 'native_function_casing' => true, + 'new_with_braces' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_null_property_initialization' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_whitespace_in_blank_line' => true, + 'ordered_imports' => true, + 'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']], + 'php_unit_mock_short_will_return' => true, + 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], + 'php_unit_test_annotation' => ['style' => 'annotation'], + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_scalar' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'return_type_declaration' => ['space_before' => 'none'], + 'single_quote' => true, + 'single_trait_insert_per_statement' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + 'whitespace_after_comma_in_array' => true, + ]) + ->setFinder($finder) +; diff --git a/composer.json b/composer.json index 77a3758..c2010de 100644 --- a/composer.json +++ b/composer.json @@ -16,5 +16,8 @@ "psr-4": { "Codeception\\Module\\": "src" } + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.22" } } diff --git a/src/MailHog.php b/src/MailHog.php index 1681a58..0d6f28b 100644 --- a/src/MailHog.php +++ b/src/MailHog.php @@ -15,122 +15,116 @@ class MailHog extends Module { - use TestsEmails; - - /** - * HTTP Client to interact with MailHog - * - * @var \GuzzleHttp\Client - */ - protected $mailhog; - - /** - * Raw email header data converted to JSON - * - * @var array - */ - protected $fetchedEmails; - - /** - * Currently selected set of email headers to work with - * - * @var array - */ - protected $currentInbox; - - /** - * Starts as the same data as the current inbox, but items are removed as they're used - * - * @var array - */ - protected $unreadInbox; - - /** - * Contains the currently open email on which test operations are conducted - * - * @var mixed - */ - protected $openedEmail; - - /** - * Codeception exposed variables - * - * @var array - */ - protected array $config = array('url', 'port', 'guzzleRequestOptions', 'deleteEmailsAfterScenario', 'timeout'); - - /** - * Codeception required variables - * - * @var array - */ - protected array $requiredFields = array('url', 'port'); - - public function _initialize() - { - $url = trim($this->config['url'], '/') . ':' . $this->config['port']; - - $timeout = 1.0; - if(isset($this->config['timeout'])) - $timeout = $this->config['timeout']; - - $options = ['base_uri' => $url, 'timeout' => $timeout]; - - $this->mailhog = new \GuzzleHttp\Client(array_merge($options, $this->config['guzzleRequestOptions'] ?? [])); - } - - /** - * Method executed after each scenario - */ - public function _after(TestInterface $test) - { - if(isset($this->config['deleteEmailsAfterScenario']) && $this->config['deleteEmailsAfterScenario']) - { - $this->deleteAllEmails(); - } - } - - /** - * Delete All Emails - * - * Accessible from tests, deletes all emails - */ - public function deleteAllEmails() - { - try + use TestsEmails; + + /** + * HTTP Client to interact with MailHog + * + * @var \GuzzleHttp\Client + */ + protected $mailhog; + + /** + * Raw email header data converted to JSON + * + * @var array + */ + protected $fetchedEmails; + + /** + * Currently selected set of email headers to work with + * + * @var array + */ + protected $currentInbox; + + /** + * Starts as the same data as the current inbox, but items are removed as they're used + * + * @var array + */ + protected $unreadInbox; + + /** + * Contains the currently open email on which test operations are conducted + * + * @var mixed + */ + protected $openedEmail; + + /** + * Codeception exposed variables + * + * @var array + */ + protected array $config = ['url', 'port', 'guzzleRequestOptions', 'deleteEmailsAfterScenario', 'timeout']; + + /** + * Codeception required variables + * + * @var array + */ + protected array $requiredFields = ['url', 'port']; + + public function _initialize() { - $this->mailhog->request('DELETE', '/api/v1/messages'); + $url = trim($this->config['url'], '/') . ':' . $this->config['port']; + + $timeout = 1.0; + if (isset($this->config['timeout'])) { + $timeout = $this->config['timeout']; + } + + $options = ['base_uri' => $url, 'timeout' => $timeout]; + + $this->mailhog = new \GuzzleHttp\Client(array_merge($options, $this->config['guzzleRequestOptions'] ?? [])); } - catch(Exception $e) + + /** + * Method executed after each scenario + */ + public function _after(TestInterface $test) { - $this->fail('Exception: ' . $e->getMessage()); + if (isset($this->config['deleteEmailsAfterScenario']) && $this->config['deleteEmailsAfterScenario']) { + $this->deleteAllEmails(); + } } - } - - /** - * Fetch Emails - * - * Accessible from tests, fetches all emails - */ - public function fetchEmails() - { - $this->fetchedEmails = array(); - - try + + /** + * Delete All Emails + * + * Accessible from tests, deletes all emails + */ + public function deleteAllEmails() { - $response = $this->mailhog->request('GET', '/api/v1/messages'); - $this->fetchedEmails = json_decode($response->getBody()); + try { + $this->mailhog->request('DELETE', '/api/v1/messages'); + } catch(Exception $e) { + $this->fail('Exception: ' . $e->getMessage()); + } } - catch(Exception $e) + + /** + * Fetch Emails + * + * Accessible from tests, fetches all emails + */ + public function fetchEmails() { - $this->fail('Exception: ' . $e->getMessage()); - } + $this->fetchedEmails = []; - $this->sortEmails($this->fetchedEmails); + try { + $response = $this->mailhog->request('GET', '/api/v1/messages'); + $this->fetchedEmails = json_decode($response->getBody()); + } catch(Exception $e) { + $this->fail('Exception: ' . $e->getMessage()); + } + + $this->sortEmails($this->fetchedEmails); - // by default, work on all emails - $this->setCurrentInbox($this->fetchedEmails); - } + // by default, work on all emails + $this->setCurrentInbox($this->fetchedEmails); + } /** * Access Inbox For * @@ -141,7 +135,7 @@ public function fetchEmails() */ public function accessInboxFor($address) { - $inbox = array(); + $inbox = []; foreach ($this->fetchedEmails as $email) { if (strpos($email->Content->Headers->To[0], $address) !== false) { @@ -168,7 +162,7 @@ public function accessInboxFor($address) */ public function accessInboxForTo($address) { - $inbox = array(); + $inbox = []; foreach ($this->fetchedEmails as $email) { if (strpos($email->Content->Headers->To[0], $address) !== false) { @@ -187,7 +181,7 @@ public function accessInboxForTo($address) */ public function accessInboxForCc($address) { - $inbox = array(); + $inbox = []; foreach ($this->fetchedEmails as $email) { if (isset($email->Content->Headers->Cc) && array_search($address, $email->Content->Headers->Cc)) { @@ -206,7 +200,7 @@ public function accessInboxForCc($address) */ public function accessInboxForBcc($address) { - $inbox = array(); + $inbox = []; foreach ($this->fetchedEmails as $email) { if (isset($email->Content->Headers->Bcc) && array_search($address, $email->Content->Headers->Bcc)) { @@ -216,310 +210,306 @@ public function accessInboxForBcc($address) $this->setCurrentInbox($inbox); } - /** - * Open Next Unread Email - * - * Pops the most recent unread email and assigns it as the email to conduct tests on - */ - public function openNextUnreadEmail() - { - $this->openedEmail = $this->getMostRecentUnreadEmail(); - } - - /** - * Get Opened Email - * - * Main method called by the tests, providing either the currently open email or the next unread one - * - * @param bool $fetchNextUnread Goes to the next Unread Email - * @return mixed Returns a JSON encoded Email - */ - protected function getOpenedEmail($fetchNextUnread = FALSE) - { - if($fetchNextUnread || $this->openedEmail == NULL) + /** + * Open Next Unread Email + * + * Pops the most recent unread email and assigns it as the email to conduct tests on + */ + public function openNextUnreadEmail() { - $this->openNextUnreadEmail(); + $this->openedEmail = $this->getMostRecentUnreadEmail(); } - return $this->openedEmail; - } - - /** - * Get Most Recent Unread Email - * - * Pops the most recent unread email, fails if the inbox is empty - * - * @return mixed Returns a JSON encoded Email - */ - protected function getMostRecentUnreadEmail() - { - if(empty($this->unreadInbox)) + /** + * Get Opened Email + * + * Main method called by the tests, providing either the currently open email or the next unread one + * + * @param bool $fetchNextUnread Goes to the next Unread Email + * @return mixed Returns a JSON encoded Email + */ + protected function getOpenedEmail($fetchNextUnread = false) { - $this->fail('Unread Inbox is Empty'); + if ($fetchNextUnread || $this->openedEmail == null) { + $this->openNextUnreadEmail(); + } + + return $this->openedEmail; } - $email = array_shift($this->unreadInbox); - return $this->getFullEmail($email->ID); - } - - /** - * Get Full Email - * - * Returns the full content of an email - * - * @param string $id ID from the header - * @return mixed Returns a JSON encoded Email - */ - protected function getFullEmail($id) - { - try + /** + * Get Most Recent Unread Email + * + * Pops the most recent unread email, fails if the inbox is empty + * + * @return mixed Returns a JSON encoded Email + */ + protected function getMostRecentUnreadEmail() { - $response = $this->mailhog->request('GET', "/api/v1/messages/{$id}"); + if (empty($this->unreadInbox)) { + $this->fail('Unread Inbox is Empty'); + } + + $email = array_shift($this->unreadInbox); + return $this->getFullEmail($email->ID); } - catch(Exception $e) + + /** + * Get Full Email + * + * Returns the full content of an email + * + * @param string $id ID from the header + * @return mixed Returns a JSON encoded Email + */ + protected function getFullEmail($id) { - $this->fail('Exception: ' . $e->getMessage()); + try { + $response = $this->mailhog->request('GET', "/api/v1/messages/{$id}"); + } catch(Exception $e) { + $this->fail('Exception: ' . $e->getMessage()); + } + $fullEmail = json_decode($response->getBody()); + return $fullEmail; } - $fullEmail = json_decode($response->getBody()); - return $fullEmail; - } - - /** - * Get Email Subject - * - * Returns the subject of an email - * - * @param mixed $email Email - * @return string Subject - */ - protected function getEmailSubject($email) - { - return $this->getDecodedEmailProperty($email, $email->Content->Headers->Subject[0]); - } - - /** - * Get Email Body - * - * Returns the body of an email - * - * @param mixed $email Email - * @return string Body - */ - protected function getEmailBody($email) - { - return $this->getDecodedEmailProperty($email, $email->Content->Body); - } - - /** - * Get Email To - * - * Returns the string containing the persons included in the To field - * - * @param mixed $email Email - * @return string To - */ - protected function getEmailTo($email) - { - return $this->getDecodedEmailProperty($email, $email->Content->Headers->To[0]); - } - - /** - * Get Email CC - * - * Returns the string containing the persons included in the CC field - * - * @param mixed $email Email - * @return string CC - */ - protected function getEmailCC($email) - { - $emailCc = ''; - if (isset($email->Content->Headers->Cc)) { - $emailCc = $this->getDecodedEmailProperty($email, $email->Content->Headers->Cc[0]); + + /** + * Get Email Subject + * + * Returns the subject of an email + * + * @param mixed $email Email + * @return string Subject + */ + protected function getEmailSubject($email) + { + return $this->getDecodedEmailProperty($email, $email->Content->Headers->Subject[0]); } - return $emailCc; - } - - /** - * Get Email BCC - * - * Returns the string containing the persons included in the BCC field - * - * @param mixed $email Email - * @return string BCC - */ - protected function getEmailBCC($email) - { - $emailBcc = ''; - if (isset($email->Content->Headers->Bcc)) { - $emailBcc = $this->getDecodedEmailProperty($email, $email->Content->Headers->Bcc[0]); + + /** + * Get Email Body + * + * Returns the body of an email + * + * @param mixed $email Email + * @return string Body + */ + protected function getEmailBody($email) + { + return $this->getDecodedEmailProperty($email, $email->Content->Body); } - return $emailBcc; - } - - /** - * Get Email Recipients - * - * Returns the string containing all of the recipients, such as To, CC and if provided BCC - * - * @param mixed $email Email - * @return string Recipients - */ - protected function getEmailRecipients($email) - { - $recipients = []; - if (isset($email->Content->Headers->To)) { - $recipients[] = $this->getEmailTo($email); + + /** + * Get Email To + * + * Returns the string containing the persons included in the To field + * + * @param mixed $email Email + * @return string To + */ + protected function getEmailTo($email) + { + return $this->getDecodedEmailProperty($email, $email->Content->Headers->To[0]); } - if (isset($email->Content->Headers->Cc)) { - $recipients[] = $this->getEmailCC($email); + + /** + * Get Email CC + * + * Returns the string containing the persons included in the CC field + * + * @param mixed $email Email + * @return string CC + */ + protected function getEmailCC($email) + { + $emailCc = ''; + if (isset($email->Content->Headers->Cc)) { + $emailCc = $this->getDecodedEmailProperty($email, $email->Content->Headers->Cc[0]); + } + return $emailCc; + } + + /** + * Get Email BCC + * + * Returns the string containing the persons included in the BCC field + * + * @param mixed $email Email + * @return string BCC + */ + protected function getEmailBCC($email) + { + $emailBcc = ''; + if (isset($email->Content->Headers->Bcc)) { + $emailBcc = $this->getDecodedEmailProperty($email, $email->Content->Headers->Bcc[0]); + } + return $emailBcc; + } + + /** + * Get Email Recipients + * + * Returns the string containing all of the recipients, such as To, CC and if provided BCC + * + * @param mixed $email Email + * @return string Recipients + */ + protected function getEmailRecipients($email) + { + $recipients = []; + if (isset($email->Content->Headers->To)) { + $recipients[] = $this->getEmailTo($email); + } + if (isset($email->Content->Headers->Cc)) { + $recipients[] = $this->getEmailCC($email); + } + if (isset($email->Content->Headers->Bcc)) { + $recipients[] = $this->getEmailBCC($email); + } + + $recipients = implode(' ', $recipients); + + return $recipients; + } + + /** + * Get Email Sender + * + * Returns the string containing the sender of the email + * + * @param mixed $email Email + * @return string Sender + */ + protected function getEmailSender($email) + { + return $this->getDecodedEmailProperty($email, $email->Content->Headers->From[0]); } - if(isset($email->Content->Headers->Bcc)) { - $recipients[] = $this->getEmailBCC($email); + + /** + * Get Email Reply To + * + * Returns the string containing the address to reply to + * + * @param mixed $email Email + * @return string ReplyTo + */ + protected function getEmailReplyTo($email) + { + return $this->getDecodedEmailProperty($email, $email->Content->Headers->{'Reply-To'}[0]); + } + + /** + * Get Email Priority + * + * Returns the priority of the email + * + * @param mixed $email Email + * @return string Priority + */ + protected function getEmailPriority($email) + { + return $this->getDecodedEmailProperty($email, $email->Content->Headers->{'X-Priority'}[0]); } - $recipients = implode(' ', $recipients); - - return $recipients; - } - - /** - * Get Email Sender - * - * Returns the string containing the sender of the email - * - * @param mixed $email Email - * @return string Sender - */ - protected function getEmailSender($email) - { - return $this->getDecodedEmailProperty($email, $email->Content->Headers->From[0]); - } - - /** - * Get Email Reply To - * - * Returns the string containing the address to reply to - * - * @param mixed $email Email - * @return string ReplyTo - */ - protected function getEmailReplyTo($email) - { - return $this->getDecodedEmailProperty($email, $email->Content->Headers->{'Reply-To'}[0]); - } - - /** - * Get Email Priority - * - * Returns the priority of the email - * - * @param mixed $email Email - * @return string Priority - */ - protected function getEmailPriority($email) - { - return $this->getDecodedEmailProperty($email, $email->Content->Headers->{'X-Priority'}[0]); - } - - /** - * Returns the decoded email property - * - * @param string $property - * @return string - */ - protected function getDecodedEmailProperty($email, $property) { - if ((string)$property != '') { - if (!empty($email->Content->Headers->{'Content-Transfer-Encoding'}) && - in_array('quoted-printable', $email->Content->Headers->{'Content-Transfer-Encoding'}) - ) { - $property = quoted_printable_decode($property); - } - if (!empty($email->Content->Headers->{'Content-Type'}[0]) && - strpos($email->Content->Headers->{'Content-Type'}[0], 'multipart/mixed') !== false - ) { - $property = quoted_printable_decode($property); - } - if (strpos($property, 'Content-Transfer-Encoding: quoted-printable') !== false) { - $property = quoted_printable_decode($property); - } - if (strpos($property, 'Content-Type: text/html') !== false) { - $property = html_entity_decode($property, ENT_QUOTES, 'UTF-8'); - } - if (strpos($property, '=?utf-8?Q?') !== false && extension_loaded('mbstring')) { - // see https://bugs.php.net/bug.php?id=68821 - // mb_decode_mimeheader does not decode "_" to spaces - we apply the proposed workaround here - $property = preg_replace_callback('/(=\?[^?]+\?Q\?)([^?]+)(\?=)/i', function($matches) { - return $matches[1] . str_replace('_', '=20', $matches[2]) . $matches[3]; - }, $property); - $property = mb_decode_mimeheader($property); - } + /** + * Returns the decoded email property + * + * @param string $property + * @return string + */ + protected function getDecodedEmailProperty($email, $property) + { + if ((string)$property != '') { + if (!empty($email->Content->Headers->{'Content-Transfer-Encoding'}) && + in_array('quoted-printable', $email->Content->Headers->{'Content-Transfer-Encoding'}) + ) { + $property = quoted_printable_decode($property); + } + if (!empty($email->Content->Headers->{'Content-Type'}[0]) && + strpos($email->Content->Headers->{'Content-Type'}[0], 'multipart/mixed') !== false + ) { + $property = quoted_printable_decode($property); + } + if (strpos($property, 'Content-Transfer-Encoding: quoted-printable') !== false) { + $property = quoted_printable_decode($property); + } + if (strpos($property, 'Content-Type: text/html') !== false) { + $property = html_entity_decode($property, ENT_QUOTES, 'UTF-8'); + } + if (strpos($property, '=?utf-8?Q?') !== false && extension_loaded('mbstring')) { + // see https://bugs.php.net/bug.php?id=68821 + // mb_decode_mimeheader does not decode "_" to spaces - we apply the proposed workaround here + $property = preg_replace_callback('/(=\?[^?]+\?Q\?)([^?]+)(\?=)/i', function ($matches) { + return $matches[1] . str_replace('_', '=20', $matches[2]) . $matches[3]; + }, $property); + $property = mb_decode_mimeheader($property); + } + } + return $property; + } + + /** + * Set Current Inbox + * + * Sets the current inbox to work on, also create a copy of it to handle unread emails + * + * @param array $inbox Inbox + */ + protected function setCurrentInbox($inbox) + { + $this->currentInbox = $inbox; + $this->unreadInbox = $inbox; + } + + /** + * Get Current Inbox + * + * Returns the complete current inbox + * + * @return array Current Inbox + */ + protected function getCurrentInbox() + { + return $this->currentInbox; + } + + /** + * Get Unread Inbox + * + * Returns the inbox containing unread emails + * + * @return array Unread Inbox + */ + protected function getUnreadInbox() + { + return $this->unreadInbox; + } + + /** + * Sort Emails + * + * Sorts the inbox based on the timestamp + * + * @param array $inbox Inbox to sort + */ + protected function sortEmails($inbox) + { + usort($inbox, [$this, 'sortEmailsByCreationDatePredicate']); + } + + /** + * Get Email To + * + * Returns the string containing the persons included in the To field + * + * @param mixed $emailA Email + * @param mixed $emailB Email + * @return int Which email should go first + */ + public static function sortEmailsByCreationDatePredicate($emailA, $emailB) + { + $sortKeyA = $emailA->Content->Headers->Date; + $sortKeyB = $emailB->Content->Headers->Date; + return ($sortKeyA > $sortKeyB) ? -1 : 1; } - return $property; - } - - /** - * Set Current Inbox - * - * Sets the current inbox to work on, also create a copy of it to handle unread emails - * - * @param array $inbox Inbox - */ - protected function setCurrentInbox($inbox) - { - $this->currentInbox = $inbox; - $this->unreadInbox = $inbox; - } - - /** - * Get Current Inbox - * - * Returns the complete current inbox - * - * @return array Current Inbox - */ - protected function getCurrentInbox() - { - return $this->currentInbox; - } - - /** - * Get Unread Inbox - * - * Returns the inbox containing unread emails - * - * @return array Unread Inbox - */ - protected function getUnreadInbox() - { - return $this->unreadInbox; - } - - /** - * Sort Emails - * - * Sorts the inbox based on the timestamp - * - * @param array $inbox Inbox to sort - */ - protected function sortEmails($inbox) - { - usort($inbox, array($this, 'sortEmailsByCreationDatePredicate')); - } - - /** - * Get Email To - * - * Returns the string containing the persons included in the To field - * - * @param mixed $emailA Email - * @param mixed $emailB Email - * @return int Which email should go first - */ - static function sortEmailsByCreationDatePredicate($emailA, $emailB) - { - $sortKeyA = $emailA->Content->Headers->Date; - $sortKeyB = $emailB->Content->Headers->Date; - return ($sortKeyA > $sortKeyB) ? -1 : 1; - } } diff --git a/src/TestsEmails.php b/src/TestsEmails.php index 6c41690..9ff7b10 100644 --- a/src/TestsEmails.php +++ b/src/TestsEmails.php @@ -10,556 +10,553 @@ namespace Codeception\Module; -use Codeception\Module; - trait TestsEmails { - /** - * Have Emails - * - * Checks if there are any emails in the inbox - */ - public function haveEmails() - { - $currentInbox = $this->getCurrentInbox(); - $this->assertGreaterThan(0, count($currentInbox)); - } - - /** - * Have Number Of Emails - * - * Checks that the amount of emails in the inbox is exactly $expected - * @params int $expected Number of expected emails - */ - public function haveNumberOfEmails($expected) - { - $currentInbox = $this->getCurrentInbox(); - $this->assertEquals($expected, count($currentInbox)); - } - - /** - * Dont Have Emails - * - * Checks that there are no emails in the inbox - */ - public function dontHaveEmails() - { - $currentInbox = $this->getCurrentInbox(); - $this->assertEquals(0, count($currentInbox)); - } - - /** - * Have Unread Emails - * - * Checks that there is at least one unread email - **/ - public function haveUnreadEmails() - { - $unreadInbox = $this->getUnreadInbox(); - $this->assertGreaterThan(0, count($unreadInbox)); - } - - /** - * Have Number Of Unread Emails - * - * Checks that the amount of emails in the unread inbox is exactly $expected - * @params int $expected Number of expected emails - */ - public function haveNumberOfUnreadEmails($expected) - { - $unreadInbox = $this->getUnreadInbox(); - $this->assertEquals($expected, count($unreadInbox)); - } - - /** - * Dont Have Unread Emails - * - * Checks that there are no unread emails in the inbox - */ - public function dontHaveUnreadEmails() - { - $unreadInbox = $this->getUnreadInbox(); - $this->assertEquals(0, count($unreadInbox)); - } - - /** - * See In Opened Email Body - * - * Validates that $expected can be found in the opened email body - * - * @param string $expected Text - */ - public function seeInOpenedEmailBody($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailBody($email, $expected); - } - - /** - * See In Opened Email Subject - * - * Validates that $expected can be found in the opened email subject - * - * @param string $expected Text - */ - public function seeInOpenedEmailSubject($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailSubject($email, $expected); - } - - /** - * Dont See In Opened Email Body - * - * Checks that $expected cannot be found in the opened email body - * - * @param string $expected Text - */ - public function dontSeeInOpenedEmailBody($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailBody($email, $expected); - } - - /** - * Dont See In Opened Email Subject - * - * Checks that $expected cannot be found in the opened email subject - * - * @param string $expected Text - */ - public function dontSeeInOpenedEmailSubject($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailSubject($email, $expected); - } - - /** - * See In Email Body - * - * Checks that the body of $email contains $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function seeInEmailBody($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailBody($email), "Email Body Contains"); - } - - /** - * Dont See In Email Body - * - * Checks that the body of $email does not contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function dontSeeInEmailBody($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailBody($email), "Email Body Doesn't Contain"); - } - - /** - * See In Email Subject - * - * Checks that the subject of $email contains $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function seeInEmailSubject($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailSubject($email), "Email Subject Contains"); - } - - /** - * Dont See In Email Subject - * - * Checks that the subject of $email does not contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function dontSeeInEmailSubject($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailSubject($email), "Email Subject Doesn't Contain"); - } - - /** - * See In Opened Email Sender - * - * Checks if the sender of the opened email contains $expected - * - * @param string $expected Text - */ - public function seeInOpenedEmailSender($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailSender($email, $expected); - } - - /** - * Dont See In Opened Email Sender - * - * Checks if the sender of the opened email does not contain $expected - * - * @param string $expected Text - */ - public function dontSeeInOpenedEmailSender($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailSender($email, $expected); - } - - /** - * See In Email Sender - * - * Checks if the sender of $email contains $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function seeInEmailSender($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailSender($email)); - } - - /** - * Dont See In Email Sender - * - * Checks if the sender of $email does not contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function dontSeeInEmailSender($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailSender($email)); - } - - /** - * See In Opened Email Reply To - * - * Checks if the ReplyTo of the opened email contains $expected - * - * @param string $expected Text - */ - public function seeInOpenedEmailReplyTo($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailReplyTo($email, $expected); - } - - /** - * Dont See In Opened Email Reply To - * - * Checks if the ReplyTo of the opened email does not contain $expected - * - * @param string $expected Text - */ - public function dontSeeInOpenedEmailReplyTo($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailReplyTo($email, $expected); - } - - /** - * See In Email Reply To - * - * Checks if the ReplyTo of $email contains $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function seeInEmailReplyTo($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailReplyTo($email)); - } - - /** - * Dont See In Email Reply To - * - * Checks if the ReplyTo of $email does not contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function dontSeeInEmailReplyTo($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailReplyTo($email)); - } - - /** - * See In Opened Email Recipients - * - * Checks that the recipients of the opened email contain $expected - * - * @param string $expected Text - */ - public function seeInOpenedEmailRecipients($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailRecipients($email, $expected); - } - - /** - * Dont See In Opened Email Recipients - * - * Checks that the recipients of the opened email do not contain $expected - * - * @param string $expected Text - */ - public function dontSeeInOpenedEmailRecipients($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailRecipients($email, $expected); - } - - /** - * See In Email Recipients - * - * Checks that the recipients of $email contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function seeInEmailRecipients($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailRecipients($email)); - } - - /** - * Dont See In Email Recipients - * - * Checks that the recipients of $email do not contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function dontSeeInEmailRecipients($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailRecipients($email)); - } - - /** - * See In Opened Email To Field - * - * Checks that the To field of the opened email contains $expected - * - * @param string $expected Text - */ - public function seeInOpenedEmailToField($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailToField($email, $expected); - } - - /** - * Dont See In Opened Email To Field - * - * Checks that the To field of the opened email does not contain $expected - * - * @param string $expected Text - */ - public function dontSeeInOpenedEmailToField($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailToField($email, $expected); - } - - /** - * See In Email To Field - * - * Checks that the To field of $email contains $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function seeInEmailToField($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailTo($email)); - } - - /** - * Dont See In Email To Field - * - * Checks that the To field of $email does not contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function dontSeeInEmailToField($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailTo($email)); - } - - /** - * See In Opened Email CC Field - * - * Checks that the CC field of the opened email contains $expected - * - * @param string $expected Text - */ - public function seeInOpenedEmailCCField($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailCCField($email, $expected); - } - - /** - * Dont See In Opened Email CC Field - * - * Checks that the CC field of the opened email does not contain $expected - * - * @param string $expected Text - */ - public function dontSeeInOpenedEmailCCField($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailCCField($email, $expected); - } - - /** - * See In Email CC Field - * - * Checks that the CC field of $email contains $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function seeInEmailCCField($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailCC($email)); - } - - /** - * Dont See In Email CC Field - * - * Checks that the CC field of $email does not contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function dontSeeInEmailCCField($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailCC($email)); - } - - /** - * See In Opened Email BCC Field - * - * Checks that the BCC field of the opened email contains $expected - * - * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. - * - * @param string $expected Text - */ - public function seeInOpenedEmailBCCField($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailBCCField($email, $expected); - } - - /** - * Dont See In Opened Email BCC Field - * - * Checks that the BCC field of the opened email does not contain $expected - * - * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. - * - * @param string $expected Text - */ - public function dontSeeInOpenedEmailBCCField($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailBCCField($email, $expected); - } - - /** - * See In Email BCC Field - * - * Checks that the BCC field of $email contains $expected - * - * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function seeInEmailBCCField($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailBCC($email)); - } - - /** - * Dont See In Email BCC Field - * - * Checks that the BCC field of $email does not contain $expected - * - * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. - * - * @param mixed $email a JSON encoded email - * @param string $expected Text - */ - public function dontSeeInEmailBCCField($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailBCC($email)); - } - - /** - * See In Opened Email Priority - * - * Checks that the priority of the opened email contains $expected - * - * @param string $expected priority - */ - public function seeInOpenedEmailPriority($expected) - { - $email = $this->getOpenedEmail(); - $this->seeInEmailPriority($email, $expected); - } - - /** - * Dont See In Opened Email Priority - * - * Checks that the priority of the opened email does not contain $expected - * - * @param string $expected priority - */ - public function dontSeeInOpenedEmailPriority($expected) - { - $email = $this->getOpenedEmail(); - $this->dontSeeInEmailPriority($email, $expected); - } - - /** - * See In Email Priority - * - * Checks that the priority of $email contains $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected priority - */ - public function seeInEmailPriority($email, $expected) - { - $this->assertStringContainsString($expected, $this->getEmailPriority($email)); - } - - /** - * Dont See In Email Priority - * - * Checks that the priority of $email does not contain $expected - * - * @param mixed $email a JSON encoded email - * @param string $expected priority - */ - public function dontSeeInEmailPriority($email, $expected) - { - $this->assertStringNotContainsString($expected, $this->getEmailPriority($email)); - } + /** + * Have Emails + * + * Checks if there are any emails in the inbox + */ + public function haveEmails() + { + $currentInbox = $this->getCurrentInbox(); + $this->assertGreaterThan(0, count($currentInbox)); + } + + /** + * Have Number Of Emails + * + * Checks that the amount of emails in the inbox is exactly $expected + * @params int $expected Number of expected emails + */ + public function haveNumberOfEmails($expected) + { + $currentInbox = $this->getCurrentInbox(); + $this->assertEquals($expected, count($currentInbox)); + } + + /** + * Dont Have Emails + * + * Checks that there are no emails in the inbox + */ + public function dontHaveEmails() + { + $currentInbox = $this->getCurrentInbox(); + $this->assertEquals(0, count($currentInbox)); + } + + /** + * Have Unread Emails + * + * Checks that there is at least one unread email + **/ + public function haveUnreadEmails() + { + $unreadInbox = $this->getUnreadInbox(); + $this->assertGreaterThan(0, count($unreadInbox)); + } + + /** + * Have Number Of Unread Emails + * + * Checks that the amount of emails in the unread inbox is exactly $expected + * @params int $expected Number of expected emails + */ + public function haveNumberOfUnreadEmails($expected) + { + $unreadInbox = $this->getUnreadInbox(); + $this->assertEquals($expected, count($unreadInbox)); + } + + /** + * Dont Have Unread Emails + * + * Checks that there are no unread emails in the inbox + */ + public function dontHaveUnreadEmails() + { + $unreadInbox = $this->getUnreadInbox(); + $this->assertEquals(0, count($unreadInbox)); + } + + /** + * See In Opened Email Body + * + * Validates that $expected can be found in the opened email body + * + * @param string $expected Text + */ + public function seeInOpenedEmailBody($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailBody($email, $expected); + } + + /** + * See In Opened Email Subject + * + * Validates that $expected can be found in the opened email subject + * + * @param string $expected Text + */ + public function seeInOpenedEmailSubject($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailSubject($email, $expected); + } + + /** + * Dont See In Opened Email Body + * + * Checks that $expected cannot be found in the opened email body + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailBody($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailBody($email, $expected); + } + + /** + * Dont See In Opened Email Subject + * + * Checks that $expected cannot be found in the opened email subject + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailSubject($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailSubject($email, $expected); + } + + /** + * See In Email Body + * + * Checks that the body of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailBody($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailBody($email), 'Email Body Contains'); + } + + /** + * Dont See In Email Body + * + * Checks that the body of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailBody($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailBody($email), "Email Body Doesn't Contain"); + } + + /** + * See In Email Subject + * + * Checks that the subject of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailSubject($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailSubject($email), 'Email Subject Contains'); + } + + /** + * Dont See In Email Subject + * + * Checks that the subject of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailSubject($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailSubject($email), "Email Subject Doesn't Contain"); + } + + /** + * See In Opened Email Sender + * + * Checks if the sender of the opened email contains $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailSender($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailSender($email, $expected); + } + + /** + * Dont See In Opened Email Sender + * + * Checks if the sender of the opened email does not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailSender($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailSender($email, $expected); + } + + /** + * See In Email Sender + * + * Checks if the sender of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailSender($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailSender($email)); + } + + /** + * Dont See In Email Sender + * + * Checks if the sender of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailSender($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailSender($email)); + } + + /** + * See In Opened Email Reply To + * + * Checks if the ReplyTo of the opened email contains $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailReplyTo($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailReplyTo($email, $expected); + } + + /** + * Dont See In Opened Email Reply To + * + * Checks if the ReplyTo of the opened email does not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailReplyTo($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailReplyTo($email, $expected); + } + + /** + * See In Email Reply To + * + * Checks if the ReplyTo of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailReplyTo($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailReplyTo($email)); + } + + /** + * Dont See In Email Reply To + * + * Checks if the ReplyTo of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailReplyTo($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailReplyTo($email)); + } /** + * See In Opened Email Recipients + * + * Checks that the recipients of the opened email contain $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailRecipients($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailRecipients($email, $expected); + } + /** + * Dont See In Opened Email Recipients + * + * Checks that the recipients of the opened email do not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailRecipients($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailRecipients($email, $expected); + } + + /** + * See In Email Recipients + * + * Checks that the recipients of $email contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailRecipients($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailRecipients($email)); + } + + /** + * Dont See In Email Recipients + * + * Checks that the recipients of $email do not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailRecipients($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailRecipients($email)); + } + + /** + * See In Opened Email To Field + * + * Checks that the To field of the opened email contains $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailToField($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailToField($email, $expected); + } + + /** + * Dont See In Opened Email To Field + * + * Checks that the To field of the opened email does not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailToField($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailToField($email, $expected); + } + + /** + * See In Email To Field + * + * Checks that the To field of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailToField($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailTo($email)); + } + + /** + * Dont See In Email To Field + * + * Checks that the To field of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailToField($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailTo($email)); + } + + /** + * See In Opened Email CC Field + * + * Checks that the CC field of the opened email contains $expected + * + * @param string $expected Text + */ + public function seeInOpenedEmailCCField($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailCCField($email, $expected); + } + + /** + * Dont See In Opened Email CC Field + * + * Checks that the CC field of the opened email does not contain $expected + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailCCField($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailCCField($email, $expected); + } + + /** + * See In Email CC Field + * + * Checks that the CC field of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailCCField($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailCC($email)); + } + + /** + * Dont See In Email CC Field + * + * Checks that the CC field of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailCCField($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailCC($email)); + } + + /** + * See In Opened Email BCC Field + * + * Checks that the BCC field of the opened email contains $expected + * + * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. + * + * @param string $expected Text + */ + public function seeInOpenedEmailBCCField($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailBCCField($email, $expected); + } + + /** + * Dont See In Opened Email BCC Field + * + * Checks that the BCC field of the opened email does not contain $expected + * + * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. + * + * @param string $expected Text + */ + public function dontSeeInOpenedEmailBCCField($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailBCCField($email, $expected); + } + + /** + * See In Email BCC Field + * + * Checks that the BCC field of $email contains $expected + * + * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function seeInEmailBCCField($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailBCC($email)); + } + + /** + * Dont See In Email BCC Field + * + * Checks that the BCC field of $email does not contain $expected + * + * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. + * + * @param mixed $email a JSON encoded email + * @param string $expected Text + */ + public function dontSeeInEmailBCCField($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailBCC($email)); + } + + /** + * See In Opened Email Priority + * + * Checks that the priority of the opened email contains $expected + * + * @param string $expected priority + */ + public function seeInOpenedEmailPriority($expected) + { + $email = $this->getOpenedEmail(); + $this->seeInEmailPriority($email, $expected); + } + + /** + * Dont See In Opened Email Priority + * + * Checks that the priority of the opened email does not contain $expected + * + * @param string $expected priority + */ + public function dontSeeInOpenedEmailPriority($expected) + { + $email = $this->getOpenedEmail(); + $this->dontSeeInEmailPriority($email, $expected); + } + + /** + * See In Email Priority + * + * Checks that the priority of $email contains $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected priority + */ + public function seeInEmailPriority($email, $expected) + { + $this->assertStringContainsString($expected, $this->getEmailPriority($email)); + } + + /** + * Dont See In Email Priority + * + * Checks that the priority of $email does not contain $expected + * + * @param mixed $email a JSON encoded email + * @param string $expected priority + */ + public function dontSeeInEmailPriority($email, $expected) + { + $this->assertStringNotContainsString($expected, $this->getEmailPriority($email)); + } + + /** * @param string $content_type_alternative MIME-part Content-Type * @return string Body */ @@ -567,7 +564,7 @@ public function grabBodyFromEmail($content_type_alternative = null) { $email = $this->getOpenedEmail(); - if( isset($content_type_alternative) ) { + if (isset($content_type_alternative)) { foreach ($email->MIME->Parts as $part) { if (!empty($part->Headers->{'Content-Type'}[0]) && strpos($part->Headers->{'Content-Type'}[0], $content_type_alternative) !== false) { @@ -578,4 +575,4 @@ public function grabBodyFromEmail($content_type_alternative = null) } return $this->getDecodedEmailProperty($email, $email->Content->Body); //return full email } -}; +} From 1e23d215aaa1c24a4bef7410fcb00378d55571c9 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 17 Jul 2023 08:14:15 +0200 Subject: [PATCH 5/7] State PHP compatibility The package most probably is compatible with more versions, but we use 8.1.x right now. Also the package didn't communicate any compatibility until now. --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c2010de..74ff3fa 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ } ], "require": { + "php": "~8.1.0", "ericmartel/codeception-email": "^1.0", "guzzlehttp/guzzle": "^6.1 || ^7.0" }, @@ -18,6 +19,7 @@ } }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.22" + "friendsofphp/php-cs-fixer": "^3.22", + "phpstan/phpstan": "^1.10" } } From 157ccd50c0593f796d24a2f63d51e7d195fe059a Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 17 Jul 2023 08:44:38 +0200 Subject: [PATCH 6/7] Add native types and PHPStan --- composer.json | 4 +- phpstan-baseline.neon | 51 +++++++++++++++++ phpstan.neon | 8 +++ src/MailHog.php | 115 ++++++++++++++------------------------- src/TestsEmails.php | 124 +++++++++++++++++++++--------------------- 5 files changed, 164 insertions(+), 138 deletions(-) create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon diff --git a/composer.json b/composer.json index 74ff3fa..afcba2c 100644 --- a/composer.json +++ b/composer.json @@ -10,8 +10,8 @@ ], "require": { "php": "~8.1.0", - "ericmartel/codeception-email": "^1.0", - "guzzlehttp/guzzle": "^6.1 || ^7.0" + "guzzlehttp/guzzle": "^6.1 || ^7.0", + "codeception/codeception": "^5.0" }, "autoload": { "psr-4": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..4b23813 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,51 @@ +parameters: + ignoreErrors: + - + message: "#^Access to an undefined property object\\:\\:\\$Body\\.$#" + count: 1 + path: src/MailHog.php + + - + message: "#^Access to an undefined property object\\:\\:\\$Content\\.$#" + count: 11 + path: src/MailHog.php + + - + message: "#^Access to an undefined property object\\:\\:\\$MIME\\.$#" + count: 1 + path: src/MailHog.php + + - + message: "#^Cannot access property \\$ID on object\\|null\\.$#" + count: 1 + path: src/MailHog.php + + - + message: "#^Method Codeception\\\\Module\\\\MailHog\\:\\:getFullEmail\\(\\) should return object but returns mixed\\.$#" + count: 1 + path: src/MailHog.php + + - + message: "#^Parameter \\#1 \\$inbox of method Codeception\\\\Module\\\\MailHog\\:\\:sortEmails\\(\\) expects array\\, mixed given\\.$#" + count: 1 + path: src/MailHog.php + + - + message: "#^Parameter \\#1 \\$string of function mb_decode_mimeheader expects string, string\\|null given\\.$#" + count: 1 + path: src/MailHog.php + + - + message: "#^Parameter \\#2 \\.\\.\\.\\$arrays of function array_merge expects array, array\\|string given\\.$#" + count: 1 + path: src/MailHog.php + + - + message: "#^Property Codeception\\\\Module\\\\MailHog\\:\\:\\$fetchedEmails \\(array\\\\) does not accept mixed\\.$#" + count: 1 + path: src/MailHog.php + + - + message: "#^Variable \\$response might not be defined\\.$#" + count: 1 + path: src/MailHog.php diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..ec413c4 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,8 @@ +includes: + - phpstan-baseline.neon +parameters: + level: max + phpVersion: 80100 + reportUnmatchedIgnoredErrors: true + paths: + - src diff --git a/src/MailHog.php b/src/MailHog.php index 0d6f28b..5e18b62 100644 --- a/src/MailHog.php +++ b/src/MailHog.php @@ -12,6 +12,7 @@ use Codeception\Module; use Codeception\TestInterface; +use Exception; class MailHog extends Module { @@ -27,46 +28,46 @@ class MailHog extends Module /** * Raw email header data converted to JSON * - * @var array + * @var array */ protected $fetchedEmails; /** * Currently selected set of email headers to work with * - * @var array + * @var array */ protected $currentInbox; /** * Starts as the same data as the current inbox, but items are removed as they're used * - * @var array + * @var array */ protected $unreadInbox; /** * Contains the currently open email on which test operations are conducted * - * @var mixed + * @var object */ protected $openedEmail; /** * Codeception exposed variables * - * @var array + * @var array */ protected array $config = ['url', 'port', 'guzzleRequestOptions', 'deleteEmailsAfterScenario', 'timeout']; /** * Codeception required variables * - * @var array + * @var array */ protected array $requiredFields = ['url', 'port']; - public function _initialize() + public function _initialize(): void { $url = trim($this->config['url'], '/') . ':' . $this->config['port']; @@ -83,7 +84,7 @@ public function _initialize() /** * Method executed after each scenario */ - public function _after(TestInterface $test) + public function _after(TestInterface $test): void { if (isset($this->config['deleteEmailsAfterScenario']) && $this->config['deleteEmailsAfterScenario']) { $this->deleteAllEmails(); @@ -95,7 +96,7 @@ public function _after(TestInterface $test) * * Accessible from tests, deletes all emails */ - public function deleteAllEmails() + public function deleteAllEmails(): void { try { $this->mailhog->request('DELETE', '/api/v1/messages'); @@ -109,7 +110,7 @@ public function deleteAllEmails() * * Accessible from tests, fetches all emails */ - public function fetchEmails() + public function fetchEmails(): void { $this->fetchedEmails = []; @@ -133,7 +134,7 @@ public function fetchEmails() * * @param string $address Recipient address' inbox */ - public function accessInboxFor($address) + public function accessInboxFor(string $address): void { $inbox = []; @@ -160,7 +161,7 @@ public function accessInboxFor($address) * * @param string $address Recipient address' inbox */ - public function accessInboxForTo($address) + public function accessInboxForTo(string $address): void { $inbox = []; @@ -179,7 +180,7 @@ public function accessInboxForTo($address) * * @param string $address Recipient address' inbox */ - public function accessInboxForCc($address) + public function accessInboxForCc(string $address): void { $inbox = []; @@ -198,7 +199,7 @@ public function accessInboxForCc($address) * * @param string $address Recipient address' inbox */ - public function accessInboxForBcc($address) + public function accessInboxForBcc(string $address): void { $inbox = []; @@ -215,7 +216,7 @@ public function accessInboxForBcc($address) * * Pops the most recent unread email and assigns it as the email to conduct tests on */ - public function openNextUnreadEmail() + public function openNextUnreadEmail(): void { $this->openedEmail = $this->getMostRecentUnreadEmail(); } @@ -226,9 +227,9 @@ public function openNextUnreadEmail() * Main method called by the tests, providing either the currently open email or the next unread one * * @param bool $fetchNextUnread Goes to the next Unread Email - * @return mixed Returns a JSON encoded Email + * @return object Returns a JSON encoded Email */ - protected function getOpenedEmail($fetchNextUnread = false) + protected function getOpenedEmail(bool $fetchNextUnread = false): object { if ($fetchNextUnread || $this->openedEmail == null) { $this->openNextUnreadEmail(); @@ -242,9 +243,9 @@ protected function getOpenedEmail($fetchNextUnread = false) * * Pops the most recent unread email, fails if the inbox is empty * - * @return mixed Returns a JSON encoded Email + * @return object Returns a JSON encoded Email */ - protected function getMostRecentUnreadEmail() + protected function getMostRecentUnreadEmail(): object { if (empty($this->unreadInbox)) { $this->fail('Unread Inbox is Empty'); @@ -260,9 +261,9 @@ protected function getMostRecentUnreadEmail() * Returns the full content of an email * * @param string $id ID from the header - * @return mixed Returns a JSON encoded Email + * @return object Returns a JSON encoded Email */ - protected function getFullEmail($id) + protected function getFullEmail(string $id): object { try { $response = $this->mailhog->request('GET', "/api/v1/messages/{$id}"); @@ -277,11 +278,8 @@ protected function getFullEmail($id) * Get Email Subject * * Returns the subject of an email - * - * @param mixed $email Email - * @return string Subject */ - protected function getEmailSubject($email) + protected function getEmailSubject(object $email): string { return $this->getDecodedEmailProperty($email, $email->Content->Headers->Subject[0]); } @@ -290,11 +288,8 @@ protected function getEmailSubject($email) * Get Email Body * * Returns the body of an email - * - * @param mixed $email Email - * @return string Body */ - protected function getEmailBody($email) + protected function getEmailBody(object $email): string { return $this->getDecodedEmailProperty($email, $email->Content->Body); } @@ -303,11 +298,8 @@ protected function getEmailBody($email) * Get Email To * * Returns the string containing the persons included in the To field - * - * @param mixed $email Email - * @return string To */ - protected function getEmailTo($email) + protected function getEmailTo(object $email): string { return $this->getDecodedEmailProperty($email, $email->Content->Headers->To[0]); } @@ -316,11 +308,8 @@ protected function getEmailTo($email) * Get Email CC * * Returns the string containing the persons included in the CC field - * - * @param mixed $email Email - * @return string CC */ - protected function getEmailCC($email) + protected function getEmailCC(object $email): string { $emailCc = ''; if (isset($email->Content->Headers->Cc)) { @@ -333,11 +322,8 @@ protected function getEmailCC($email) * Get Email BCC * * Returns the string containing the persons included in the BCC field - * - * @param mixed $email Email - * @return string BCC */ - protected function getEmailBCC($email) + protected function getEmailBCC(object $email): string { $emailBcc = ''; if (isset($email->Content->Headers->Bcc)) { @@ -350,11 +336,8 @@ protected function getEmailBCC($email) * Get Email Recipients * * Returns the string containing all of the recipients, such as To, CC and if provided BCC - * - * @param mixed $email Email - * @return string Recipients */ - protected function getEmailRecipients($email) + protected function getEmailRecipients(object $email): string { $recipients = []; if (isset($email->Content->Headers->To)) { @@ -376,11 +359,8 @@ protected function getEmailRecipients($email) * Get Email Sender * * Returns the string containing the sender of the email - * - * @param mixed $email Email - * @return string Sender */ - protected function getEmailSender($email) + protected function getEmailSender(object $email): string { return $this->getDecodedEmailProperty($email, $email->Content->Headers->From[0]); } @@ -389,11 +369,8 @@ protected function getEmailSender($email) * Get Email Reply To * * Returns the string containing the address to reply to - * - * @param mixed $email Email - * @return string ReplyTo */ - protected function getEmailReplyTo($email) + protected function getEmailReplyTo(object $email): string { return $this->getDecodedEmailProperty($email, $email->Content->Headers->{'Reply-To'}[0]); } @@ -402,22 +379,16 @@ protected function getEmailReplyTo($email) * Get Email Priority * * Returns the priority of the email - * - * @param mixed $email Email - * @return string Priority */ - protected function getEmailPriority($email) + protected function getEmailPriority(object $email): string { return $this->getDecodedEmailProperty($email, $email->Content->Headers->{'X-Priority'}[0]); } /** * Returns the decoded email property - * - * @param string $property - * @return string */ - protected function getDecodedEmailProperty($email, $property) + protected function getDecodedEmailProperty(object $email, string $property): string { if ((string)$property != '') { if (!empty($email->Content->Headers->{'Content-Transfer-Encoding'}) && @@ -453,9 +424,9 @@ protected function getDecodedEmailProperty($email, $property) * * Sets the current inbox to work on, also create a copy of it to handle unread emails * - * @param array $inbox Inbox + * @param array $inbox Inbox */ - protected function setCurrentInbox($inbox) + protected function setCurrentInbox(array $inbox): void { $this->currentInbox = $inbox; $this->unreadInbox = $inbox; @@ -466,9 +437,9 @@ protected function setCurrentInbox($inbox) * * Returns the complete current inbox * - * @return array Current Inbox + * @return array Current Inbox */ - protected function getCurrentInbox() + protected function getCurrentInbox(): array { return $this->currentInbox; } @@ -478,9 +449,9 @@ protected function getCurrentInbox() * * Returns the inbox containing unread emails * - * @return array Unread Inbox + * @return array Unread Inbox */ - protected function getUnreadInbox() + protected function getUnreadInbox(): array { return $this->unreadInbox; } @@ -490,9 +461,9 @@ protected function getUnreadInbox() * * Sorts the inbox based on the timestamp * - * @param array $inbox Inbox to sort + * @param array $inbox Inbox to sort */ - protected function sortEmails($inbox) + protected function sortEmails(array $inbox): void { usort($inbox, [$this, 'sortEmailsByCreationDatePredicate']); } @@ -501,12 +472,8 @@ protected function sortEmails($inbox) * Get Email To * * Returns the string containing the persons included in the To field - * - * @param mixed $emailA Email - * @param mixed $emailB Email - * @return int Which email should go first */ - public static function sortEmailsByCreationDatePredicate($emailA, $emailB) + public static function sortEmailsByCreationDatePredicate(object $emailA, object $emailB): int { $sortKeyA = $emailA->Content->Headers->Date; $sortKeyB = $emailB->Content->Headers->Date; diff --git a/src/TestsEmails.php b/src/TestsEmails.php index 9ff7b10..f17d46c 100644 --- a/src/TestsEmails.php +++ b/src/TestsEmails.php @@ -17,7 +17,7 @@ trait TestsEmails * * Checks if there are any emails in the inbox */ - public function haveEmails() + public function haveEmails(): void { $currentInbox = $this->getCurrentInbox(); $this->assertGreaterThan(0, count($currentInbox)); @@ -29,7 +29,7 @@ public function haveEmails() * Checks that the amount of emails in the inbox is exactly $expected * @params int $expected Number of expected emails */ - public function haveNumberOfEmails($expected) + public function haveNumberOfEmails(int $expected): void { $currentInbox = $this->getCurrentInbox(); $this->assertEquals($expected, count($currentInbox)); @@ -40,7 +40,7 @@ public function haveNumberOfEmails($expected) * * Checks that there are no emails in the inbox */ - public function dontHaveEmails() + public function dontHaveEmails(): void { $currentInbox = $this->getCurrentInbox(); $this->assertEquals(0, count($currentInbox)); @@ -51,7 +51,7 @@ public function dontHaveEmails() * * Checks that there is at least one unread email **/ - public function haveUnreadEmails() + public function haveUnreadEmails(): void { $unreadInbox = $this->getUnreadInbox(); $this->assertGreaterThan(0, count($unreadInbox)); @@ -63,7 +63,7 @@ public function haveUnreadEmails() * Checks that the amount of emails in the unread inbox is exactly $expected * @params int $expected Number of expected emails */ - public function haveNumberOfUnreadEmails($expected) + public function haveNumberOfUnreadEmails(int $expected): void { $unreadInbox = $this->getUnreadInbox(); $this->assertEquals($expected, count($unreadInbox)); @@ -74,7 +74,7 @@ public function haveNumberOfUnreadEmails($expected) * * Checks that there are no unread emails in the inbox */ - public function dontHaveUnreadEmails() + public function dontHaveUnreadEmails(): void { $unreadInbox = $this->getUnreadInbox(); $this->assertEquals(0, count($unreadInbox)); @@ -87,7 +87,7 @@ public function dontHaveUnreadEmails() * * @param string $expected Text */ - public function seeInOpenedEmailBody($expected) + public function seeInOpenedEmailBody(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailBody($email, $expected); @@ -100,7 +100,7 @@ public function seeInOpenedEmailBody($expected) * * @param string $expected Text */ - public function seeInOpenedEmailSubject($expected) + public function seeInOpenedEmailSubject(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailSubject($email, $expected); @@ -113,7 +113,7 @@ public function seeInOpenedEmailSubject($expected) * * @param string $expected Text */ - public function dontSeeInOpenedEmailBody($expected) + public function dontSeeInOpenedEmailBody(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailBody($email, $expected); @@ -126,7 +126,7 @@ public function dontSeeInOpenedEmailBody($expected) * * @param string $expected Text */ - public function dontSeeInOpenedEmailSubject($expected) + public function dontSeeInOpenedEmailSubject(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailSubject($email, $expected); @@ -137,10 +137,10 @@ public function dontSeeInOpenedEmailSubject($expected) * * Checks that the body of $email contains $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function seeInEmailBody($email, $expected) + public function seeInEmailBody(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailBody($email), 'Email Body Contains'); } @@ -150,10 +150,10 @@ public function seeInEmailBody($email, $expected) * * Checks that the body of $email does not contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function dontSeeInEmailBody($email, $expected) + public function dontSeeInEmailBody(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailBody($email), "Email Body Doesn't Contain"); } @@ -163,10 +163,10 @@ public function dontSeeInEmailBody($email, $expected) * * Checks that the subject of $email contains $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function seeInEmailSubject($email, $expected) + public function seeInEmailSubject(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailSubject($email), 'Email Subject Contains'); } @@ -176,10 +176,10 @@ public function seeInEmailSubject($email, $expected) * * Checks that the subject of $email does not contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function dontSeeInEmailSubject($email, $expected) + public function dontSeeInEmailSubject(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailSubject($email), "Email Subject Doesn't Contain"); } @@ -191,7 +191,7 @@ public function dontSeeInEmailSubject($email, $expected) * * @param string $expected Text */ - public function seeInOpenedEmailSender($expected) + public function seeInOpenedEmailSender(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailSender($email, $expected); @@ -204,7 +204,7 @@ public function seeInOpenedEmailSender($expected) * * @param string $expected Text */ - public function dontSeeInOpenedEmailSender($expected) + public function dontSeeInOpenedEmailSender(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailSender($email, $expected); @@ -215,10 +215,10 @@ public function dontSeeInOpenedEmailSender($expected) * * Checks if the sender of $email contains $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function seeInEmailSender($email, $expected) + public function seeInEmailSender(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailSender($email)); } @@ -228,10 +228,10 @@ public function seeInEmailSender($email, $expected) * * Checks if the sender of $email does not contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function dontSeeInEmailSender($email, $expected) + public function dontSeeInEmailSender(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailSender($email)); } @@ -243,7 +243,7 @@ public function dontSeeInEmailSender($email, $expected) * * @param string $expected Text */ - public function seeInOpenedEmailReplyTo($expected) + public function seeInOpenedEmailReplyTo(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailReplyTo($email, $expected); @@ -256,7 +256,7 @@ public function seeInOpenedEmailReplyTo($expected) * * @param string $expected Text */ - public function dontSeeInOpenedEmailReplyTo($expected) + public function dontSeeInOpenedEmailReplyTo(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailReplyTo($email, $expected); @@ -267,10 +267,10 @@ public function dontSeeInOpenedEmailReplyTo($expected) * * Checks if the ReplyTo of $email contains $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function seeInEmailReplyTo($email, $expected) + public function seeInEmailReplyTo(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailReplyTo($email)); } @@ -280,10 +280,10 @@ public function seeInEmailReplyTo($email, $expected) * * Checks if the ReplyTo of $email does not contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function dontSeeInEmailReplyTo($email, $expected) + public function dontSeeInEmailReplyTo(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailReplyTo($email)); } @@ -295,7 +295,7 @@ public function dontSeeInEmailReplyTo($email, $expected) * * @param string $expected Text */ - public function seeInOpenedEmailRecipients($expected) + public function seeInOpenedEmailRecipients(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailRecipients($email, $expected); @@ -308,7 +308,7 @@ public function seeInOpenedEmailRecipients($expected) * * @param string $expected Text */ - public function dontSeeInOpenedEmailRecipients($expected) + public function dontSeeInOpenedEmailRecipients(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailRecipients($email, $expected); @@ -319,10 +319,10 @@ public function dontSeeInOpenedEmailRecipients($expected) * * Checks that the recipients of $email contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function seeInEmailRecipients($email, $expected) + public function seeInEmailRecipients(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailRecipients($email)); } @@ -332,10 +332,10 @@ public function seeInEmailRecipients($email, $expected) * * Checks that the recipients of $email do not contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function dontSeeInEmailRecipients($email, $expected) + public function dontSeeInEmailRecipients(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailRecipients($email)); } @@ -347,7 +347,7 @@ public function dontSeeInEmailRecipients($email, $expected) * * @param string $expected Text */ - public function seeInOpenedEmailToField($expected) + public function seeInOpenedEmailToField(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailToField($email, $expected); @@ -360,7 +360,7 @@ public function seeInOpenedEmailToField($expected) * * @param string $expected Text */ - public function dontSeeInOpenedEmailToField($expected) + public function dontSeeInOpenedEmailToField(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailToField($email, $expected); @@ -371,10 +371,10 @@ public function dontSeeInOpenedEmailToField($expected) * * Checks that the To field of $email contains $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function seeInEmailToField($email, $expected) + public function seeInEmailToField(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailTo($email)); } @@ -384,10 +384,10 @@ public function seeInEmailToField($email, $expected) * * Checks that the To field of $email does not contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function dontSeeInEmailToField($email, $expected) + public function dontSeeInEmailToField(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailTo($email)); } @@ -399,7 +399,7 @@ public function dontSeeInEmailToField($email, $expected) * * @param string $expected Text */ - public function seeInOpenedEmailCCField($expected) + public function seeInOpenedEmailCCField(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailCCField($email, $expected); @@ -412,7 +412,7 @@ public function seeInOpenedEmailCCField($expected) * * @param string $expected Text */ - public function dontSeeInOpenedEmailCCField($expected) + public function dontSeeInOpenedEmailCCField(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailCCField($email, $expected); @@ -423,10 +423,10 @@ public function dontSeeInOpenedEmailCCField($expected) * * Checks that the CC field of $email contains $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function seeInEmailCCField($email, $expected) + public function seeInEmailCCField(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailCC($email)); } @@ -436,10 +436,10 @@ public function seeInEmailCCField($email, $expected) * * Checks that the CC field of $email does not contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function dontSeeInEmailCCField($email, $expected) + public function dontSeeInEmailCCField(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailCC($email)); } @@ -453,7 +453,7 @@ public function dontSeeInEmailCCField($email, $expected) * * @param string $expected Text */ - public function seeInOpenedEmailBCCField($expected) + public function seeInOpenedEmailBCCField(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailBCCField($email, $expected); @@ -468,7 +468,7 @@ public function seeInOpenedEmailBCCField($expected) * * @param string $expected Text */ - public function dontSeeInOpenedEmailBCCField($expected) + public function dontSeeInOpenedEmailBCCField(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailBCCField($email, $expected); @@ -481,10 +481,10 @@ public function dontSeeInOpenedEmailBCCField($expected) * * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function seeInEmailBCCField($email, $expected) + public function seeInEmailBCCField(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailBCC($email)); } @@ -496,10 +496,10 @@ public function seeInEmailBCCField($email, $expected) * * Warning: it is possible for an email to have its BCC field empty, it doesn't mean that another instance of the same email doesn't exist. * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected Text */ - public function dontSeeInEmailBCCField($email, $expected) + public function dontSeeInEmailBCCField(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailBCC($email)); } @@ -511,7 +511,7 @@ public function dontSeeInEmailBCCField($email, $expected) * * @param string $expected priority */ - public function seeInOpenedEmailPriority($expected) + public function seeInOpenedEmailPriority(string $expected): void { $email = $this->getOpenedEmail(); $this->seeInEmailPriority($email, $expected); @@ -524,7 +524,7 @@ public function seeInOpenedEmailPriority($expected) * * @param string $expected priority */ - public function dontSeeInOpenedEmailPriority($expected) + public function dontSeeInOpenedEmailPriority(string $expected): void { $email = $this->getOpenedEmail(); $this->dontSeeInEmailPriority($email, $expected); @@ -535,10 +535,10 @@ public function dontSeeInOpenedEmailPriority($expected) * * Checks that the priority of $email contains $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected priority */ - public function seeInEmailPriority($email, $expected) + public function seeInEmailPriority(object $email, string $expected): void { $this->assertStringContainsString($expected, $this->getEmailPriority($email)); } @@ -548,19 +548,19 @@ public function seeInEmailPriority($email, $expected) * * Checks that the priority of $email does not contain $expected * - * @param mixed $email a JSON encoded email + * @param object $email a JSON encoded email * @param string $expected priority */ - public function dontSeeInEmailPriority($email, $expected) + public function dontSeeInEmailPriority(object $email, string $expected): void { $this->assertStringNotContainsString($expected, $this->getEmailPriority($email)); } /** * @param string $content_type_alternative MIME-part Content-Type - * @return string Body + * @return string|null Body */ - public function grabBodyFromEmail($content_type_alternative = null) + public function grabBodyFromEmail(string $content_type_alternative = null): ?string { $email = $this->getOpenedEmail(); From a2649c82c622e9429acf4b1ac9539221e4d3fa4f Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 17 Jul 2023 08:48:12 +0200 Subject: [PATCH 7/7] Add CI --- .github/workflows/test.yml | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..806aff3 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,79 @@ +name: Test + +on: + push: + branches: + - '**' + +jobs: + check-composer: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.1" + coverage: none + tools: composer:v2 + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Validate composer.json + run: composer validate + + php-linting: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.1" + coverage: none + + - name: PHP lint + run: "find *.php src/ -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l" + + coding-guideline: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.1" + coverage: none + tools: composer:v2 + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: composer install --no-progress + + - name: Coding Guideline + run: PHP_CS_FIXER_IGNORE_ENV=1 ./vendor/bin/php-cs-fixer fix --dry-run --diff + + code-quality: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.1" + coverage: none + tools: composer:v2 + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies with expected TYPO3 version + run: composer install --no-progress + + - name: Code Quality (by PHPStan) + run: ./vendor/bin/phpstan analyse