' formatting)
- // Test body HTML
- private static $test_body = "Header provider strategic
"
- . "consulting support conversation advertisements policy promotional request.
"
- . "Option purpose programming
";
-
- public function setUp() : void
+ protected string $from_address = "from@example.com";
+
+ protected string $from_name = "From Tester";
+
+ protected string $test_body = "Header provider strategic
"
+ . "consulting support conversation advertisements policy promotional request.
"
+ . "Option purpose programming
";
+
+ protected function getTestDsn(string $regionValue = ''): string
+ {
+ return "mailgunsync+api://{$this->test_api_domain}:{$this->test_api_key}@default"
+ . ($regionValue !== '' ? "?region={$regionValue}" : "");
+ }
+
+ public function setUp(): void
{
parent::setUp();
- // Avoid using TestMailer for this test
- Injector::inst()->registerService(new MailgunMailer(), Mailer::class);
+
+ // Avoid using TestMailer for test
+ $transportFactory = Injector::inst()->create(SilverStripeEmailTransportFactory::class);
+ $this->assertInstanceOf(TransportFactory::class, $transportFactory);
+ $params = [
+ 'dsn' => $this->getTestDsn()
+ ];
+ $transport = $transportFactory->create(\Symfony\Component\Mailer\Transport\TransportInterface::class, $params);
+ Injector::inst()->registerService(new SymfonyMailer($transport), MailerInterface::class);
+
// use MailgunEmail
Injector::inst()->registerService(MailgunEmail::create(), Email::class);
// use TestMessage
- Injector::inst()->registerService(TestMessage::create(), MessageConnector::class);
+ Injector::inst()->registerService(new TestMessage($this->getTestDsn()), MessageConnector::class);
+
+ // use TransportFactory
+ Injector::inst()->registerService(new TransportFactory(), SilverStripeEmailTransportFactory::class);
// modify some config values for tests
- // never send via a job
- Config::modify()->set(Base::class, 'api_domain', $this->test_api_domain);
- Config::modify()->set(Base::class, 'api_key', $this->test_api_key);
+ // by default, do not send via a queued job
Config::modify()->set(Base::class, 'send_via_job', 'no');
+ // turn api test mode 'on'
Config::modify()->set(Base::class, 'api_testmode', true);
}
+ /**
+ * Test that the expected transport is returned based on mailgunsync+api:// DSN
+ */
+ public function testTransportFactoryTransportReturn(): void
+ {
+ $transportFactory = Injector::inst()->create(SilverStripeEmailTransportFactory::class);
+ $this->assertInstanceOf(TransportFactory::class, $transportFactory);
+ $params = [
+ 'dsn' => $this->getTestDsn()
+ ];
+ $transport = $transportFactory->create(\Symfony\Component\Mailer\Transport\TransportInterface::class, $params);
+ $this->assertInstanceOf(MailgunSyncApiTransport::class, $transport);
+ }
+
+ /**
+ * Test that sendmail transport is returned when DSN points to that
+ */
+ public function testTransportFactorySendmailTransportReturn(): void
+ {
+ $transportFactory = Injector::inst()->create(SilverStripeEmailTransportFactory::class);
+ $this->assertInstanceOf(TransportFactory::class, $transportFactory);
+ $params = [
+ 'dsn' => 'sendmail://default'
+ ];
+ $transport = $transportFactory->create(\Symfony\Component\Mailer\Transport\TransportInterface::class, $params);
+ $this->assertInstanceOf(\Symfony\Component\Mailer\Transport\SendmailTransport::class, $transport);
+ }
+
/**
* Test that the API domain configured is maintained
*/
- public function testApiDomain() {
- $currentValue = Config::inst()->get(Base::class, 'api_domain');
- $value = "testing.example.org";
- Config::modify()->set(Base::class, 'api_domain', $value);
- $connector = MessageConnector::create();
- $result = $connector->getApiDomain();
- $this->assertEquals($value, $result);
- Config::modify()->set(Base::class, 'api_domain', $currentValue);
+ public function testApiDomain(): void
+ {
+ $connector = MessageConnector::create($this->getTestDsn());
+ $this->assertEquals($this->test_api_domain, $connector->getApiDomain());
}
/**
* Test that the API endpoint configured is maintained
*/
- public function testApiEndpoint() {
-
+ public function testApiEndpoint(): void
+ {
$value = 'API_ENDPOINT_EU';
Config::modify()->set(Base::class, 'api_endpoint_region', $value);
- $connector = MessageConnector::create();
- $domains = $connector->getClient();
+ $connector = MessageConnector::create($this->getTestDsn($value));
+ $connector->getClient();
// assert that the expected URL value is what was set on the client
- $this->assertEquals(constant(Base::class . "::{$value}"), $connector->getApiEndpointRegion());
+ $this->assertEquals($value, $connector->getApiEndpointRegion());
// switch to default region
$value = '';
Config::modify()->set(Base::class, 'api_endpoint_region', $value);
- $connector = MessageConnector::create();
- $domains = $connector->getClient();
+ $connector = MessageConnector::create($this->getTestDsn());
+ $connector->getClient();
// when no value is set, the default region URL is used
$this->assertEquals('', $connector->getApiEndpointRegion());
}
- protected function getCustomParameters($to_address, $send_in) : array {
+ protected function getCustomParameters($to_address, $send_in): array
+ {
$variables = [
'test' => 'true',
'foo' => 'bar',
@@ -129,24 +173,25 @@ protected function getCustomParameters($to_address, $send_in) : array {
'headers' => $headers,
'recipient-variables' => $recipient_variables
];
- if($send_in > 0) {
+ if ($send_in > 0) {
$customParameters['send-in'] = $send_in;
}
+
return $customParameters;
}
/**
* test mailer delivery only, no sync or event checking, just that we get the expected response
+ * @return mixed[]
*/
- public function testMailerDelivery($subject = "test_mailer_delivery", $send_in = 0)
+ public function testMailerDelivery(string $subject = "test_mailer_delivery", $send_in = 0): array
{
-
- $to_address = self::config()->get('to_address');
- $to_name = self::config()->get('to_name');
+ $to_address = $this->to_address;
+ $to_name = $this->to_name;
$this->assertNotEmpty($to_address);
- $from_address = self::config()->get('from_address');
- $from_name = self::config()->get('from_name');
+ $from_address = $this->from_address;
+ $from_name = $this->from_name;
$this->assertNotEmpty($from_address);
$from = [
@@ -158,25 +203,28 @@ public function testMailerDelivery($subject = "test_mailer_delivery", $send_in =
$email = Email::create();
+ $this->assertInstanceOf(MailgunEmail::class, $email);
+
$email->setFrom($from);
$email->setTo($to);
$email->setCc(["cc@example.com" => "Cc Person"]);
$email->setBcc(["bcc@example.com" => "Bcc Person"]);
$email->setSubject($subject);
- if ($cc = self::config()->get('cc_address')) {
- $email->setCc($cc);
- }
- $htmlBody = self::config()->get('test_body');
- $email->setBody( $htmlBody );
+
+ $htmlBody = $this->test_body;
+ $email->setBody($htmlBody);
$customParameters = $this->getCustomParameters($to_address, $send_in);
+ /** @var \NSWDPC\Messaging\Mailgun\Email\MailgunEmail $email */
$email->setCustomParameters($customParameters);
// send the email, returns a message_id if delivered
+ $email->send();
- $response = $email->send();
- if(Config::inst()->get(Base::class, 'send_via_job') == 'no') {
- $this->assertEquals($response, TestMessage::MSG_ID);
+ $response = TestMessage::getSendDataValue('response');
+ if (Config::inst()->get(Base::class, 'send_via_job') == 'no') {
+ $this->assertInstanceOf(\Mailgun\Model\Message\SendResponse::class, $response);
+ $this->assertEquals(TestMessage::MSG_ID, MessageConnector::cleanMessageId($response->getId()));
} else {
// via job
$this->assertInstanceOf(QueuedJobDescriptor::class, $response);
@@ -185,44 +233,44 @@ public function testMailerDelivery($subject = "test_mailer_delivery", $send_in =
$sendData = TestMessage::getSendData();
$this->assertEquals(
- "{$from_name} <{$from_address}>",
- $sendData['parameters']['from'] ,
+ "\"{$from_name}\" <{$from_address}>",
+ $sendData['parameters']['from'],
"From: mismatch"
);
$this->assertEquals(
- "{$to_name} <{$to_address}>",
+ "\"{$to_name}\" <{$to_address}>",
$sendData['parameters']['to'],
"To: mismatch"
);
$this->assertEquals(
- "Cc Person ",
+ '"Cc Person" ',
$sendData['parameters']['cc'],
"Cc: mismatch"
);
$this->assertEquals(
- "Bcc Person ",
+ '"Bcc Person" ',
$sendData['parameters']['bcc'],
"Bcc: mismatch"
);
- foreach($customParameters['options'] as $k=>$v) {
- $this->assertEquals( $sendData['parameters']["o:{$k}"], $v, "Option $k failed");
+ foreach ($customParameters['options'] as $k => $v) {
+ $this->assertEquals($sendData['parameters']["o:{$k}"], $v, "Option {$k} failed");
}
- foreach($customParameters['variables'] as $k=>$v) {
- $this->assertEquals( $sendData['parameters']["v:{$k}"], $v , "Variable $k failed");
+ foreach ($customParameters['variables'] as $k => $v) {
+ $this->assertEquals($sendData['parameters']["v:{$k}"], $v, "Variable {$k} failed");
}
- foreach($customParameters['headers'] as $k=>$v) {
- $this->assertEquals( $sendData['parameters']["h:{$k}"], $v , "Header $k failed");
+ foreach ($customParameters['headers'] as $k => $v) {
+ $this->assertEquals($sendData['parameters']["h:{$k}"], $v, "Header {$k} failed");
}
- $this->assertEquals( json_encode($customParameters['recipient-variables']), $sendData['parameters']['recipient-variables'] );
+ $this->assertEquals(json_encode($customParameters['recipient-variables']), $sendData['parameters']['recipient-variables']);
- $this->assertEquals($htmlBody, $sendData['parameters']['html'] );
+ $this->assertEquals($htmlBody, $sendData['parameters']['html']);
return $sendData;
}
@@ -230,7 +278,8 @@ public function testMailerDelivery($subject = "test_mailer_delivery", $send_in =
/**
* Test delivery via a Job
*/
- public function testJobMailerDelivery() {
+ public function testJobMailerDelivery(): void
+ {
Config::modify()->set(Base::class, 'send_via_job', 'yes');
// send message
$subject = "test_mailer_delivery_job";
@@ -244,7 +293,8 @@ public function testJobMailerDelivery() {
/**
* Test delivery via a Job
*/
- public function testJobMailerDeliveryInFuture() {
+ public function testJobMailerDeliveryInFuture(): void
+ {
Config::modify()->set(Base::class, 'send_via_job', 'yes');
// send message
$subject = "test_mailer_delivery_job_future";
@@ -258,68 +308,62 @@ public function testJobMailerDeliveryInFuture() {
}
- protected function checkJobData(QueuedJobDescriptor $job, $subject, $send_in) {
-
-
+ protected function checkJobData(QueuedJobDescriptor $job, $subject, $send_in)
+ {
$this->assertEquals(SendJob::class, $job->Implementation);
$data = @unserialize($job->SavedJobData ?? '');
+ $this->assertObjectHasProperty('parameters', $data);
- $this->assertEquals(
- Config::inst()->get(Base::class, 'api_domain'),
- $data->domain
- );
-
- $to = self::config()->get('to_name') . " <" . self::config()->get('to_address') . ">";
+ $to = "\"{$this->to_name}\" <{$this->to_address}>";
$this->assertEquals($to, $data->parameters['to']);
- $from = self::config()->get('from_name') . " <" . self::config()->get('from_address') . ">";
+ $from = "\"{$this->from_name}\" <{$this->from_address}>";
$this->assertEquals($from, $data->parameters['from']);
- $cc = "Cc Person ";
+ $cc = '"Cc Person" ';
$this->assertEquals($cc, $data->parameters['cc']);
- $bcc = "Bcc Person ";
+ $bcc = '"Bcc Person" ';
$this->assertEquals($bcc, $data->parameters['bcc']);
$this->assertEquals($subject, $data->parameters['subject']);
- $this->assertEquals(self::config()->get('test_body'), $data->parameters['html']);
+ $this->assertEquals($this->test_body, $data->parameters['html']);
- $customParameters = $this->getCustomParameters(self::config()->get('to_address'), $send_in);
+ $customParameters = $this->getCustomParameters($this->to_address, $send_in);
- foreach($customParameters['options'] as $k=>$v) {
- $this->assertEquals( $data->parameters["o:{$k}"], $v, "Option $k failed");
+ foreach ($customParameters['options'] as $k => $v) {
+ $this->assertEquals($data->parameters["o:{$k}"], $v, "Option {$k} failed");
}
- foreach($customParameters['variables'] as $k=>$v) {
- $this->assertEquals( $data->parameters["v:{$k}"], $v , "Variable $k failed");
+ foreach ($customParameters['variables'] as $k => $v) {
+ $this->assertEquals($data->parameters["v:{$k}"], $v, "Variable {$k} failed");
}
- foreach($customParameters['headers'] as $k=>$v) {
- $this->assertEquals( $data->parameters["h:{$k}"], $v , "Header $k failed");
+ foreach ($customParameters['headers'] as $k => $v) {
+ $this->assertEquals($data->parameters["h:{$k}"], $v, "Header {$k} failed");
}
- $this->assertEquals( json_encode($customParameters['recipient-variables']), $data->parameters['recipient-variables'] );
-
+ $this->assertEquals(json_encode($customParameters['recipient-variables']), $data->parameters['recipient-variables']);
}
/**
* Test always from setting
*/
- public function testAlwaysFrom() {
-
+ public function testAlwaysFrom(): void
+ {
$alwaysFromEmail = 'alwaysfrom@example.com';
- Config::modify()->set(MailgunMailer::class, 'always_from', $alwaysFromEmail);
+ Config::modify()->set(Email::class, 'send_all_emails_from', $alwaysFromEmail);
- $to_address = self::config()->get('to_address');
- $to_name = self::config()->get('to_name');
+ $to_address = $this->to_address;
+ $to_name = $this->to_name;
$this->assertNotEmpty($to_address);
- $from_address = self::config()->get('from_address');
- $from_name = self::config()->get('from_name');
+ $from_address = $this->from_address;
+ $from_name = $this->from_name;
$this->assertNotEmpty($from_address);
$from = [
@@ -336,12 +380,12 @@ public function testAlwaysFrom() {
$email->setTo($to);
$email->setSubject($subject);
- $response = $email->send();
+ $email->send();
- $this->assertEquals(TestMessage::MSG_ID, $response);
+ $response = TestMessage::getSendDataValue('response');
+ $this->assertEquals(TestMessage::MSG_ID, MessageConnector::cleanMessageId($response->getId()));
$sendData = TestMessage::getSendData();
-
$this->assertEquals(
$alwaysFromEmail,
$sendData['parameters']['from'],
@@ -352,23 +396,26 @@ public function testAlwaysFrom() {
/**
* test API delivery only
*/
- public function testAPIDelivery()
+ public function testAPIDelivery(): void
{
-
Config::modify()->set(Base::class, 'send_via_job', 'no');
- $connector = MessageConnector::create();
- $to = $to_address = self::config()->get('to_address');
- $to_name = self::config()->get('to_name');
- if ($to_name) {
+ $connector = MessageConnector::create($this->getTestDsn());
+ $to = $this->to_address;
+ $to_address = $this->to_address;
+ $to_name = $this->to_name;
+ if ($to_name !== '') {
$to = $to_name . ' <' . $to_address . '>';
}
+
$this->assertNotEmpty($to_address);
- $from = $from_address = self::config()->get('from_address');
- $from_name = self::config()->get('from_name');
- if ($from_name) {
+ $from = $this->from_address;
+ $from_address = $this->from_address;
+ $from_name = $this->from_name;
+ if ($from_name !== '') {
$from = $from_name . ' <' . $from_address . '>';
}
+
$this->assertNotEmpty($from_address);
$subject = "test_api_delivery";
@@ -383,13 +430,9 @@ public function testAPIDelivery()
'to' => $to,
'subject' => $subject,
'text' => '',
- 'html' => self::config()->get('test_body')
+ 'html' => $this->test_body
];
- if ($cc = self::config()->get('cc_address')) {
- $parameters['cc'] = $cc;
- }
-
$response = $connector->send($parameters);
$this->assertTrue($response && ($response instanceof SendResponse));
$message_id = $response->getId();
@@ -399,16 +442,89 @@ public function testAPIDelivery()
$this->assertArrayHasKey('parameters', $sendData);
- foreach(['o:testmode','o:tag','from','to','subject','text','html'] as $key) {
+ foreach (['o:testmode','o:tag','from','to','subject','text','html'] as $key) {
$this->assertEquals($parameters[ $key ], $sendData['parameters'][ $key ]);
}
}
/**
- * Test sending with default values set
+ * Test that tags can be set via Taggable
*/
- public function testSendWithDefaultConfiguration() {
+ public function testTaggableEmail(): void
+ {
+ $limit = 3;
+
+ Config::modify()->set(ProjectTags::class, 'tag', '');
+ Config::modify()->set(ProjectTags::class, 'tag_limit', $limit);
+
+ $to_address = $this->to_address;
+ $to_name = $this->to_name;
+ $this->assertNotEmpty($to_address);
+
+ $from_address = $this->from_address;
+ $from_name = $this->from_name;
+ $this->assertNotEmpty($from_address);
+
+ $from = [
+ $from_address => $from_name,
+ ];
+ $to = [
+ $to_address => $to_name,
+ ];
+
+ $subject = "test_taggable_email";
+
+ $email = Email::create();
+ $this->assertTrue($email instanceof MailgunEmail, "Email needs to be an instance of MailgunEmail");
+ $email->setFrom($from);
+ $email->setTo($to);
+ $email->setSubject($subject);
+
+ $email->setBody($this->test_body);
+
+ $tags = ['tagheader1','tagheader2','tagheader3'];
+ $email->setNotificationTags($tags);
+
+ $tags = $email->getNotificationTags();
+ $this->assertEquals($limit, count($tags));
+
+ // Send message
+ $email->send();
+ $response = TestMessage::getSendDataValue('response');
+
+ $this->assertEquals(TestMessage::MSG_ID, MessageConnector::cleanMessageId($response->getId()));
+ $sendData = TestMessage::getSendData();
+
+ $this->assertArrayHasKey('parameters', $sendData);
+
+ $this->assertArrayHasKey('o:tag', $sendData['parameters']);
+ $this->assertEquals($tags, $sendData['parameters']['o:tag']);
+
+ $tooManyTags = ['tagheader1','tagheader2','tagheader3', 'tagheader4'];
+ $expectedTags = ['tagheader1','tagheader2','tagheader3'];
+ $email->setNotificationTags($tooManyTags);
+ $this->assertEquals($expectedTags, $email->getNotificationTags());
+
+ // Send message again ...
+ $email->send();
+ $response = TestMessage::getSendDataValue('response');
+
+ $this->assertEquals(TestMessage::MSG_ID, MessageConnector::cleanMessageId($response->getId()));
+
+ $sendData = TestMessage::getSendData();
+
+ $this->assertArrayHasKey('parameters', $sendData);
+
+ $this->assertArrayHasKey('o:tag', $sendData['parameters']);
+ $this->assertEquals($expectedTags, $sendData['parameters']['o:tag']);
+ }
+
+ /**
+ * Test sending with default values set
+ */
+ public function testSendWithDefaultConfiguration(): void
+ {
$overrideTo = 'allemails@example.com';
$overrideFrom = 'allemailsfrom@example.com';
$overrideCc = 'ccallemailsto@example.com';
@@ -420,12 +536,12 @@ public function testSendWithDefaultConfiguration() {
Config::modify()->set(Email::class, 'cc_all_emails_to', $overrideCc);
Config::modify()->set(Email::class, 'bcc_all_emails_to', [ $overrideBcc => $overrideBccName ]);
- $to_address = self::config()->get('to_address');
- $to_name = self::config()->get('to_name');
+ $to_address = $this->to_address;
+ $to_name = $this->to_name;
$this->assertNotEmpty($to_address);
- $from_address = self::config()->get('from_address');
- $from_name = self::config()->get('from_name');
+ $from_address = $this->from_address;
+ $from_name = $this->from_name;
$this->assertNotEmpty($from_address);
$from = [
@@ -442,13 +558,15 @@ public function testSendWithDefaultConfiguration() {
$email->setBcc(['bcctest1@example.com' => 'bcctest 1', 'bcctest2@example.com' => 'bcctest 2']);
$email->setSubject("Email with default configuration set");
- $response = $email->send();
+ $email->send();
- $this->assertEquals(TestMessage::MSG_ID, $response);
+ $response = TestMessage::getSendDataValue('response');
+
+ $this->assertEquals(TestMessage::MSG_ID, MessageConnector::cleanMessageId($response->getId()));
$sendData = TestMessage::getSendData();
- foreach(['domain','parameters','sentVia','client','in'] as $key) {
+ foreach (['domain','parameters','sentVia','client','in'] as $key) {
$this->assertArrayHasKey($key, $sendData);
}
@@ -459,21 +577,21 @@ public function testSendWithDefaultConfiguration() {
$this->assertEquals($overrideTo, $sendData['parameters']['to']);
$this->assertEquals($overrideFrom, $sendData['parameters']['from']);
- $this->assertContains( $overrideCc, explode(",", $sendData['parameters']['cc']) );
- $this->assertContains( "{$overrideBccName} <{$overrideBcc}>", explode(",", $sendData['parameters']['bcc']) );
-
+ $this->assertContains($overrideCc, explode(",", (string) $sendData['parameters']['cc']));
+ $this->assertContains("\"{$overrideBccName}\" <{$overrideBcc}>", explode(",", (string) $sendData['parameters']['bcc']));
}
/**
* test a message with attachments
*/
- public function testAttachmentDelivery() {
- $to_address = self::config()->get('to_address');
- $to_name = self::config()->get('to_name');
+ public function testAttachmentDelivery(): void
+ {
+ $to_address = $this->to_address;
+ $to_name = $this->to_name;
$this->assertNotEmpty($to_address);
- $from_address = self::config()->get('from_address');
- $from_name = self::config()->get('from_name');
+ $from_address = $this->from_address;
+ $from_name = $this->from_name;
$this->assertNotEmpty($from_address);
$from = [
@@ -490,49 +608,59 @@ public function testAttachmentDelivery() {
$email->setFrom($from);
$email->setTo($to);
$email->setSubject($subject);
- $htmlBody = self::config()->get('test_body');
- $email->setBody( $htmlBody );
+
+ $htmlBody = $this->test_body;
+ $email->setBody($htmlBody);
$files = [
"test_attachment.pdf" => 'application/pdf',
"test_attachment.txt" => 'text/plain'
];
$f = 1;
- foreach($files as $file => $mimetype) {
+ foreach ($files as $file => $mimetype) {
$email->addAttachment(
- dirname(__FILE__) . "/attachments/{$file}",
+ __DIR__ . "/attachments/{$file}",
$file,
$mimetype
);
$f++;
}
- $response = $email->send();
+ $email->send();
$sendData = TestMessage::getSendData();
$this->assertArrayHasKey('parameters', $sendData);
$this->assertArrayHasKey('attachment', $sendData['parameters']);
- $attachments = $sendData['parameters']['attachment'];
+
+ // Symfony attachments
+ $symfonyAttachments = $email->getAttachments();
+ $this->assertEquals(count($files), count($symfonyAttachments));
+ foreach ($symfonyAttachments as $symfonyAttachment) {
+ $this->assertInstanceOf(\Symfony\Component\Mime\Part\DataPart::class, $symfonyAttachment);
+ }
+
+ // Mailgun formatted attachments
+ $mailgunAttachments = $sendData['parameters']['attachment'];
$f = 1;
- $this->assertEquals(count($files), count($attachments));
- foreach($attachments as $attachment) {
- $this->assertArrayHasKey( 'filename', $attachment );
- $this->assertArrayHasKey( 'mimetype', $attachment );
- $this->assertArrayHasKey( 'fileContent', $attachment );
- foreach($files as $file => $mimetype) {
- if($file == $attachment['filename']) {
- $this->assertEquals($mimetype, $attachment['mimetype']);
- $this->assertNotEmpty($attachment['fileContent']);
+ $this->assertEquals(count($files), count($mailgunAttachments));
+ foreach ($mailgunAttachments as $mailgunAttachment) {
+ $this->assertArrayHasKey('filename', $mailgunAttachment);
+ $this->assertArrayHasKey('mimetype', $mailgunAttachment);
+ $this->assertArrayHasKey('fileContent', $mailgunAttachment);
+ foreach ($files as $file => $mimetype) {
+ if ($file == $mailgunAttachment['filename']) {
+ $this->assertEquals($mimetype, $mailgunAttachment['mimetype']);
+ $this->assertNotEmpty($mailgunAttachment['fileContent']);
$this->assertEquals(
- file_get_contents( dirname(__FILE__) . "/attachments/{$file}" ),
- $attachment['fileContent']
+ file_get_contents(__DIR__ . "/attachments/{$file}"),
+ $mailgunAttachment['fileContent']
);
}
}
+
$f++;
}
}
-
}
diff --git a/tests/README.md b/tests/README.md
index 2ebd2d8..e53dfc7 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -1,36 +1,11 @@
# Test help
-The tests here cover basic delivery of messages via the configured ```Mailer``` and directly to the Mailgun PHP SDK.
+The tests here cover basic delivery of messages via `Email` and directly to the Mailgun PHP SDK.
There are also webhook tests that use sample POSTed values retrieved from actual webhook requests.
## Running
+ `TestMessage` is registered as the connector service between the Mailer and the Mailgun PHP SDK
++ Emails are captured by TestMessage and return mock response
+ Submissions from tests set o:testmode='yes' in the request to avoid message leakage
-
-## Configuration
-
-+ Ensure the ```NSWDPC\Messaging\Mailgun\Connector\Base``` yml is correct for your setup. Use a project yml config file (`/mysite/_config` or `/app/_config` config.yml)
-+ Add a copy of the below to your project configuration, with relevant changes
-
-```yml
-NSWDPC\Messaging\Mailgun\MailgunSyncTest:
- # a test recipient address - where test emails will be sent
- to_address : 'recipient@example.com'
-
- # a test recipient name
- to_name : 'Some Recipient'
-
- # a Cc address to use in tests (optional)
- cc_address : 'cc@example.com'
-
- # a test sender address
- from_address : 'sender@example.com'
-
- # a test sender name
- from_name : 'Some Sender'
-
- # content for the message body
- test_body : ''
-```
diff --git a/tests/TestMessage.php b/tests/TestMessage.php
index 7d57bf0..ce6213b 100644
--- a/tests/TestMessage.php
+++ b/tests/TestMessage.php
@@ -1,9 +1,11 @@
sendViaJob();
- switch ($send_via_job) {
- case 'yes':
- $this->sentVia = 'job';
- $response = $this->queueAndSend($domain, $parameters, $in);
- break;
- case 'when-attachments':
- if (!empty($parameters['attachment'])) {
- $this->sentVia = 'job-as-attachments';
- $response = $this->queueAndSend($domain, $parameters, $in);
- break;
- }
- case 'no':
- default:
- $this->sentVia = 'direct-to-api';
- $response = SendResponse::create(['id' => self::MSG_ID, 'message' => self::MSG_MESSAGE]);
- break;
+ if ($send_via_job === 'yes') {
+ $this->sentVia = 'job';
+ $response = $this->queueAndSend($domain, $parameters, $in);
+ } elseif ($send_via_job === 'when-attachments') {
+ $this->sentVia = 'job-as-attachments';
+ $response = $this->queueAndSend($domain, $parameters, $in);
+ } else {
+ $this->sentVia = 'direct-to-api';
+ $response = SendResponse::create(['id' => self::MSG_ID, 'message' => self::MSG_MESSAGE]);
}
// Store message info
@@ -79,6 +72,8 @@ protected function sendMessage(array $parameters) {
'sentVia' => $this->sentVia,
'client' => $this->getClient(),
'domain' => $this->getApiDomain(),
+ 'key' => $this->getApiKey(),
+ 'region' => $this->getApiEndpointRegion(),
'response' => $response
]);
@@ -88,15 +83,24 @@ protected function sendMessage(array $parameters) {
/**
* Set data that would be used
*/
- public function setSendData(array $data) {
+ public function setSendData(array $data)
+ {
self::$sendData = $data;
}
/**
* Get data that would be used
*/
- public static function getSendData() : array {
+ public static function getSendData(): array
+ {
return self::$sendData;
}
+ /**
+ * Get a specific data value that would be used
+ */
+ public static function getSendDataValue(string $key): mixed
+ {
+ return self::$sendData[$key] ?? null;
+ }
}
diff --git a/tests/WebhookTest.php b/tests/WebhookTest.php
index 46a0e80..0e0a74f 100644
--- a/tests/WebhookTest.php
+++ b/tests/WebhookTest.php
@@ -4,74 +4,91 @@
use NSWDPC\Messaging\Mailgun\Connector\Base;
use NSWDPC\Messaging\Mailgun\Connector\Webhook;
-use NSWDPC\Messaging\Mailgun\MailgunEvent;
+use NSWDPC\Messaging\Mailgun\Controllers\MailgunWebHook;
+use NSWDPC\Messaging\Mailgun\Models\MailgunEvent;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Core\Config\Config;
+use SilverStripe\Core\Environment;
/**
- * Tests for RequestHandler and HTTPRequest.
- * We've set up a simple URL handling model based on
- * https://36ca20005a6091432f680c4bff2191a4.m.pipedream.net
+ * Tests for RequestHandler and HTTPRequest
*/
class WebhookTest extends FunctionalTest
{
+ protected string $webhook_filter_variable = 'test-filter-var-curr';
- private $webhook_filter_variable = 'skjhgiehg943753-"';
- private $webhook_previous_filter_variable = 'snsd875bslw[';
+ protected string $webhook_previous_filter_variable = 'test-filter-var-prev';
+
+ protected string $webhook_signing_key = 'TEST_SHOULD_PASS';
+
+ protected string $test_api_key = 'webhook_api_key';
+
+ protected string $test_api_domain = 'webhook.example.net';
+
+ protected string $test_api_region = 'API_ENDPOINT_EU';
protected $usesDatabase = true;
- public function setUp() : void {
+ public function setUp(): void
+ {
parent::setUp();
- Config::modify()->set(Base::class, 'webhook_filter_variable', $this->webhook_filter_variable);
- Config::modify()->set(Base::class, 'webhook_previous_filter_variable', $this->webhook_previous_filter_variable);
- Config::modify()->set(Base::class, 'webhooks_enabled', true);
+ Environment::setEnv('MAILGUN_WEBHOOK_API_KEY', $this->test_api_key);
+ Environment::setEnv('MAILGUN_WEBHOOK_DOMAIN', $this->test_api_domain);
+ Environment::setEnv('MAILGUN_WEBHOOK_REGION', $this->test_api_region);
+ Environment::setEnv('MAILGUN_WEBHOOK_FILTER_VARIABLE', $this->webhook_filter_variable);
+ Environment::setEnv('MAILGUN_WEBHOOK_PREVIOUS_FILTER_VARIABLE', $this->webhook_previous_filter_variable);
+ Environment::setEnv('MAILGUN_WEBHOOK_SIGNING_KEY', $this->webhook_signing_key);
+ Config::modify()->set(MailgunWebHook::class, 'webhooks_enabled', true);
+ }
+
+ protected function getTestDsn(): string
+ {
+ $domain = Environment::getEnv('MAILGUN_WEBHOOK_DOMAIN');
+ $key = Environment::getEnv('MAILGUN_WEBHOOK_API_KEY');
+ return "mailgunsync+api://{$domain}:{$key}@default";
}
/**
* Get test data from disk
*/
- protected function getWebhookRequestData($event_type) {
- return file_get_contents( dirname(__FILE__) . "/webhooks/{$event_type}.json");
+ protected function getWebhookRequestData($event_type): string|false
+ {
+ return file_get_contents(__DIR__ . "/webhooks/{$event_type}.json");
}
/**
* Our configured endpoint for submitting POST data
*/
- protected function getSubmissionUrl() {
+ protected function getSubmissionUrl(): string
+ {
return '_wh/submit';
}
/**
* Webhook Mailgun API connector
*/
- protected function getConnector() {
- return Webhook::create();
- }
-
- /**
- * Set a signing key in Configuration
- * @param string $signing_key
- */
- protected function setSigningKey($signing_key) {
- Config::modify()->set(Base::class, 'webhook_signing_key', $signing_key);
+ protected function getConnector()
+ {
+ return Webhook::create($this->getTestDsn());
}
/**
* Replace the signature on the request data with something to trigger success/error
- * @param string $signing_key
- * @param string $request_data
+ * @param string $request_data JSON encoded request data from a test payload
* @return array
*/
- protected function setSignatureOnRequest($signing_key, $request_data) {
+ protected function setSignatureOnRequest(string $request_data)
+ {
$decoded = json_decode($request_data, true);
$connector = $this->getConnector();
+ // sign the signature
$signature = $connector->sign_token($decoded['signature']);
$decoded['signature']['signature'] = $signature;
return $decoded;
}
- protected function setWebhookFilterVariable($data, $value) {
+ protected function setWebhookFilterVariable(array $data, $value): array
+ {
$data['event-data']['user-variables']['wfv'] = $value;
return $data;
}
@@ -81,45 +98,45 @@ protected function setWebhookFilterVariable($data, $value) {
* and one that should fail
* @param string $type
*/
- protected function sendWebhookRequest($type) {
+ protected function sendWebhookRequest($type)
+ {
- $signing_key = "TEST_SHOULD_PASS";
- $this->setSigningKey($signing_key);
+ $signingKey = Environment::getEnv('MAILGUN_WEBHOOK_SIGNING_KEY');
$url = $this->getSubmissionUrl();
$headers = [
'Content-Type' => "application/json"
];
$session = null;
- $data = $this->setSignatureOnRequest($signing_key, $this->getWebhookRequestData($type));
- $data = $this->setWebhookFilterVariable($data, $this->webhook_filter_variable);
+ $data = $this->setSignatureOnRequest($this->getWebhookRequestData($type));
+ $data = $this->setWebhookFilterVariable($data, Environment::getEnv('MAILGUN_WEBHOOK_FILTER_VARIABLE'));
+
$cookies = null;
- $body = json_encode($data, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
+ $body = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
$response = $this->post($url, $data, $headers, $session, $body, $cookies);
$this->assertEquals(
200,
$response->getStatusCode(),
- 'Expected success response with correct signing_key failed: ' . $response->getStatusCode() . "/" . $response->getStatusDescription()
+ 'Expected success response with correct signing_key ' . $signingKey . ' failed: ' . $response->getStatusCode() . "/" . $response->getStatusDescription()
);
$event = \Mailgun\Model\Event\Event::create($data['event-data']);
// test if the event was saved
$record = MailgunEvent::get()->filter('EventId', $event->getId())->first();
- $this->assertTrue( $record && $record->exists() , "DB Mailgun event does not exist for event {$event->getId()}");
+ $this->assertTrue($record && $record->exists(), "DB Mailgun event does not exist for event {$event->getId()}");
// change the webhook config variable to the previous var
- $data = $this->setWebhookFilterVariable($data, $this->webhook_previous_filter_variable);
+ $data = $this->setWebhookFilterVariable($data, Environment::getEnv('MAILGUN_WEBHOOK_PREVIOUS_FILTER_VARIABLE'));
$response = $this->post($url, $data, $headers, $session, json_encode($data, JSON_UNESCAPED_SLASHES), $cookies);
$this->assertEquals(
200,
$response->getStatusCode(),
- 'Expected success response with correct signing_key failed: ' . $response->getStatusCode() . "/" . $response->getStatusDescription()
+ 'Expected success response with correct signing_key ' . $signingKey . ' failed: ' . $response->getStatusCode() . "/" . $response->getStatusDescription()
);
-
// change the webhook variable to something else completely
$data = $this->setWebhookFilterVariable($data, 'not going to work');
$response = $this->post($url, $data, $headers, $session, json_encode($data, JSON_UNESCAPED_SLASHES), $cookies);
@@ -130,48 +147,51 @@ protected function sendWebhookRequest($type) {
);
// remove webhook variable and test
- unset( $data['event-data']['user-variables']['wfv'] );
- Config::modify()->set(Base::class, 'webhook_filter_variable', '');
- Config::modify()->set(Base::class, 'webhook_previous_filter_variable', '');
-
- // change the signing key in config, it should fail now
- $signing_key = "YOU_SHALL_NOT_PASS";
- $this->setSigningKey($signing_key);
+ unset($data['event-data']['user-variables']['wfv']);
+ Environment::setEnv('MAILGUN_WEBHOOK_FILTER_VARIABLE', '');
+ Environment::setEnv('MAILGUN_WEBHOOK_PREVIOUS_FILTER_VARIABLE', '');
+ // change the signing key, it should fail now as the payload signatures are signed with the 'webhook_signing_key' value
+ Environment::setEnv('MAILGUN_WEBHOOK_SIGNING_KEY', "YOU_SHALL_NOT_PASS");
$response = $this->post($url, $data, $headers, $session, json_encode($data, JSON_UNESCAPED_SLASHES), $cookies);
$this->assertEquals(
406,
$response->getStatusCode(),
'Expected failed response code 406 with incorrect signing_key but got ' . $response->getStatusCode() . "/" . $response->getStatusDescription()
);
-
}
- public function testWebookDelivered() {
+ public function testWebhookDelivered(): void
+ {
$this->sendWebhookRequest("delivered");
}
- public function testWebookClick() {
+ public function testWebhookClick(): void
+ {
$this->sendWebhookRequest("clicked");
}
- public function testWebookOpened() {
+ public function testWebhookOpened(): void
+ {
$this->sendWebhookRequest("opened");
}
- public function testWebookFailedPermanent() {
+ public function testWebhookFailedPermanent(): void
+ {
$this->sendWebhookRequest("failed_permanent");
}
- public function testWebookFailedTemporary() {
+ public function testWebhookFailedTemporary(): void
+ {
$this->sendWebhookRequest("failed_temporary");
}
- public function testWebookUnsubscribed() {
+ public function testWebhookUnsubscribed(): void
+ {
$this->sendWebhookRequest("unsubscribed");
}
- public function testWebookComplained() {
+ public function testWebhookComplained(): void
+ {
$this->sendWebhookRequest("complained");
}
-
}