diff --git a/composer.json b/composer.json index a592c50..5e6c88c 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "require-dev": { "phpunit/phpunit": "~4.8", "php-http/guzzle6-adapter": "^1.0", - "guzzlehttp/psr7": "^1.4" + "guzzlehttp/psr7": "^1.4", + "nyholm/nsa": "^1.1" }, "autoload": { "psr-0": { diff --git a/src/Mailgun/Api/Message.php b/src/Mailgun/Api/Message.php index 8f77fbc..7f45273 100644 --- a/src/Mailgun/Api/Message.php +++ b/src/Mailgun/Api/Message.php @@ -11,6 +11,7 @@ namespace Mailgun\Api; use Mailgun\Assert; use Mailgun\Exception\InvalidArgumentException; +use Mailgun\Message\BatchMessage; use Mailgun\Model\Message\SendResponse; use Mailgun\Model\Message\ShowResponse; @@ -19,6 +20,17 @@ use Mailgun\Model\Message\ShowResponse; */ class Message extends HttpApi { + /** + * @param string $domain + * @param bool $autoSend + * + * @return BatchMessage + */ + public function getBatchMessage($domain, $autoSend = true) + { + return new BatchMessage($this, $domain, $autoSend); + } + /** * @param string $domain * @param array $params diff --git a/src/Mailgun/Mailgun.php b/src/Mailgun/Mailgun.php index 0fde7c6..7e8acf6 100644 --- a/src/Mailgun/Mailgun.php +++ b/src/Mailgun/Mailgun.php @@ -285,7 +285,7 @@ class Mailgun /** * @return MessageBuilder * - * @deprecated Will be removed in 3.0 + * @deprecated Will be removed in 3.0. */ public function MessageBuilder() { @@ -308,7 +308,7 @@ class Mailgun * * @return BatchMessage * - * @deprecated Will be removed in 3.0 + * @deprecated Will be removed in 3.0. Use Mailgun::messages()::getBatchMessage(). */ public function BatchMessage($workingDomain, $autoSend = true) { diff --git a/src/Mailgun/Message/BatchMessage.php b/src/Mailgun/Message/BatchMessage.php new file mode 100644 index 0000000..159cf55 --- /dev/null +++ b/src/Mailgun/Message/BatchMessage.php @@ -0,0 +1,134 @@ +api = $messageApi; + $this->domain = $domain; + $this->autoSend = $autoSend; + } + + /** + * @param string $headerName + * @param string $address + * @param array $variables { + * + * @var string $id + * @var string $full_name + * @var string $first + * @var string $last + * } + * + * @throws MissingRequiredParameter + * @throws TooManyRecipients + */ + protected function addRecipient($headerName, $address, array $variables) + { + if (array_key_exists($headerName, $this->counters['recipients'])) { + if ($this->counters['recipients'][$headerName] === self::RECIPIENT_COUNT_LIMIT) { + if (false === $this->autoSend) { + throw TooManyRecipients::whenAutoSendDisabled(); + } + $this->finalize(); + } + } + + parent::addRecipient($headerName, $address, $variables); + + if (array_key_exists($headerName, $this->counters['recipients']) && !array_key_exists('id', $variables)) { + $variables['id'] = $headerName.'_'.$this->counters['recipients'][$headerName]; + } + + $this->batchRecipientAttributes[(string) $address] = $variables; + } + + /** + * @throws MissingRequiredParameter + */ + public function finalize() + { + $message = $this->message; + + if (empty($this->domain)) { + throw new RuntimeException('You must call BatchMessage::setDomain before sending messages.'); + } elseif (empty($message['from'])) { + throw MissingRequiredParameter::create('from'); + } elseif (empty($message['to'])) { + throw MissingRequiredParameter::create('to'); + } elseif (empty($message['subject'])) { + throw MissingRequiredParameter::create('subject'); + } elseif (empty($message['text']) && empty($message['html'])) { + throw MissingRequiredParameter::create('text" or "html'); + } else { + $message['recipient-variables'] = json_encode($this->batchRecipientAttributes); + $response = $this->api->send($this->domain, $message); + + $this->batchRecipientAttributes = []; + $this->counters['recipients']['to'] = 0; + $this->counters['recipients']['cc'] = 0; + $this->counters['recipients']['bcc'] = 0; + unset($this->message['to']); + + $this->messageIds[] = $response->getId(); + } + } + + /** + * @return string[] + */ + public function getMessageIds() + { + return $this->messageIds; + } +} diff --git a/src/Mailgun/Message/Exceptions/LimitExceeded.php b/src/Mailgun/Message/Exceptions/LimitExceeded.php new file mode 100644 index 0000000..e034eb7 --- /dev/null +++ b/src/Mailgun/Message/Exceptions/LimitExceeded.php @@ -0,0 +1,20 @@ + [ + 'to' => 0, + 'cc' => 0, + 'bcc' => 0, + ], + 'attributes' => [ + 'attachment' => 0, + 'campaign_id' => 0, + 'custom_option' => 0, + 'tag' => 0, + ], + ]; + + /** + * @param array $params + * @param string $key + * @param mixed $default + * + * @return mixed + */ + private function get($params, $key, $default) + { + if (array_key_exists($key, $params)) { + return $params[$key]; + } + + return $default; + } + + /** + * @param array $params { + * + * @var string $full_name + * @var string $first + * @var string $last + * } + * + * @return string + */ + private function getFullName(array $params) + { + if (isset($params['full_name'])) { + return $this->get($params, 'full_name', ''); + } + + return trim(sprintf('%s %s', $this->get($params, 'first', ''), $this->get($params, 'last', ''))); + } + + /** + * @param string $address + * @param array $params { + * + * @var string $full_name + * @var string $first + * @var string $last + * } + * + * @return string + */ + protected function parseAddress($address, array $variables) + { + $fullName = $this->getFullName($variables); + if (!empty($fullName)) { + return sprintf('"%s" <%s>', $fullName, $address); + } + + return $address; + } + + /** + * @param string $headerName + * @param string $address + * @param array $variables { + * + * @var string $full_name + * @var string $first + * @var string $last + * } + */ + protected function addRecipient($headerName, $address, array $variables) + { + $compiledAddress = $this->parseAddress($address, $variables); + + if ('h:reply-to' === $headerName) { + $this->message[$headerName] = $compiledAddress; + } elseif (isset($this->message[$headerName])) { + $this->message[$headerName][] = $compiledAddress; + } else { + $this->message[$headerName] = [$compiledAddress]; + } + if (array_key_exists($headerName, $this->counters['recipients'])) { + $this->counters['recipients'][$headerName] += 1; + } + } + + /** + * @param string $address + * @param array $variables { + * + * @var string $id If used with BatchMessage + * @var string $full_name + * @var string $first + * @var string $last + * } + * + * @throws TooManyRecipients + */ + public function addToRecipient($address, array $variables = []) + { + if ($this->counters['recipients']['to'] > self::RECIPIENT_COUNT_LIMIT) { + throw TooManyRecipients::create('to'); + } + $this->addRecipient('to', $address, $variables); + } + + /** + * @param string $address + * @param array $variables { + * + * @var string $id If used with BatchMessage + * @var string $full_name + * @var string $first + * @var string $last + * } + * + * @throws TooManyRecipients + */ + public function addCcRecipient($address, array $variables = []) + { + if ($this->counters['recipients']['cc'] > self::RECIPIENT_COUNT_LIMIT) { + throw TooManyRecipients::create('cc'); + } + + $this->addRecipient('cc', $address, $variables); + } + + /** + * @param string $address + * @param array $variables { + * + * @var string $id If used with BatchMessage + * @var string $full_name + * @var string $first + * @var string $last + * } + * + * @throws TooManyRecipients + */ + public function addBccRecipient($address, array $variables) + { + if ($this->counters['recipients']['bcc'] > self::RECIPIENT_COUNT_LIMIT) { + throw TooManyRecipients::create('bcc'); + } + + $this->addRecipient('bcc', $address, $variables); + } + + /** + * @param string $address + * @param array $variables { + * + * @var string $id If used with BatchMessage + * @var string $full_name + * @var string $first + * @var string $last + * } + */ + public function setFromAddress($address, array $variables = []) + { + $this->addRecipient('from', $address, $variables); + } + + /** + * @param string $address + * @param array $variables { + * + * @var string $id If used with BatchMessage + * @var string $full_name + * @var string $first + * @var string $last + * } + */ + public function setReplyToAddress($address, array $variables = []) + { + $this->addRecipient('h:reply-to', $address, $variables); + } + + /** + * @param string $subject + */ + public function setSubject($subject) + { + $this->message['subject'] = $subject; + } + + /** + * @param string $headerName + * @param mixed $headerData + */ + public function addCustomHeader($headerName, $headerData) + { + if (!preg_match('/^h:/i', $headerName)) { + $headerName = 'h:'.$headerName; + } + + if (!array_key_exists($headerName, $this->message)) { + $this->message[$headerName] = $headerData; + } else { + if (is_array($this->message[$headerName])) { + $this->message[$headerName][] = $headerData; + } else { + $this->message[$headerName] = [$this->message[$headerName], $headerData]; + } + } + } + + /** + * @param string $textBody + */ + public function setTextBody($textBody) + { + $this->message['text'] = $textBody; + } + + /** + * @param string $htmlBody + * + * @return string + */ + public function setHtmlBody($htmlBody) + { + $this->message['html'] = $htmlBody; + } + + /** + * @param string $attachmentPath + * @param string|null $attachmentName + */ + public function addAttachment($attachmentPath, $attachmentName = null) + { + if (!isset($this->message['attachment'])) { + $this->message['attachment'] = []; + } + + $this->message['attachment'][] = [ + 'filePath' => $attachmentPath, + 'remoteName' => $attachmentName, + ]; + } + + /** + * @param string $inlineImagePath + * @param string|null $inlineImageName + */ + public function addInlineImage($inlineImagePath, $inlineImageName = null) + { + if (!isset($this->message['inline'])) { + $this->message['inline'] = []; + } + + $this->message['inline'][] = [ + 'filePath' => $inlineImagePath, + 'remoteName' => $inlineImageName, + ]; + } + + /** + * @param bool $enabled + */ + public function setTestMode($enabled) + { + $this->message['o:testmode'] = $this->boolToString($enabled); + } + + /** + * @param string $campaignId + * + * @throws LimitExceeded + */ + public function addCampaignId($campaignId) + { + if ($this->counters['attributes']['campaign_id'] >= self::CAMPAIGN_ID_LIMIT) { + throw LimitExceeded::create('campaigns', self::CAMPAIGN_ID_LIMIT); + } + if (isset($this->message['o:campaign'])) { + array_push($this->message['o:campaign'], (string) $campaignId); + } else { + $this->message['o:campaign'] = [(string) $campaignId]; + } + $this->counters['attributes']['campaign_id'] += 1; + } + + /** + * @param string $tag + * + * @throws LimitExceeded + */ + public function addTag($tag) + { + if ($this->counters['attributes']['tag'] >= self::TAG_LIMIT) { + throw LimitExceeded::create('tags', self::TAG_LIMIT); + } + + if (isset($this->message['o:tag'])) { + array_push($this->message['o:tag'], $tag); + } else { + $this->message['o:tag'] = [$tag]; + } + $this->counters['attributes']['tag'] += 1; + } + + /** + * @param bool $enabled + */ + public function setDkim($enabled) + { + $this->message['o:dkim'] = $this->boolToString($enabled); + } + + /** + * @param bool $enabled + * + * @return string + */ + public function setOpenTracking($enabled) + { + $this->message['o:tracking-opens'] = $this->boolToString($enabled); + } + + /** + * @param bool $enabled + * + * @return string + */ + public function setClickTracking($enabled) + { + $this->message['o:tracking-clicks'] = $this->boolToString($enabled); + } + + /** + * @param string $timeDate + * @param string|null $timeZone + * + * @return string + */ + public function setDeliveryTime($timeDate, $timeZone = null) + { + if (null !== $timeZone) { + $timeZoneObj = new \DateTimeZone($timeZone); + } else { + $timeZoneObj = new \DateTimeZone('UTC'); + } + + $dateTimeObj = new \DateTime($timeDate, $timeZoneObj); + $formattedTimeDate = $dateTimeObj->format(\DateTime::RFC2822); + $this->message['o:deliverytime'] = $formattedTimeDate; + + return $this->message['o:deliverytime']; + } + + /** + * @param string $customName + * @param mixed $data + */ + public function addCustomData($customName, $data) + { + $this->message['v:'.$customName] = json_encode($data); + } + + /** + * @param string $parameterName + * @param mixed $data + * + * @return mixed + */ + public function addCustomParameter($parameterName, $data) + { + if (isset($this->message[$parameterName])) { + $this->message[$parameterName][] = $data; + } else { + $this->message[$parameterName] = [$data]; + } + + return $this->message[$parameterName]; + } + + /** + * @param array $message + */ + public function setMessage($message) + { + $this->message = $message; + } + + /** + * @return array + */ + public function getMessage() + { + return $this->message; + } + + /** + * @param $enabled + * + * @return string + */ + private function boolToString($enabled) + { + if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) { + $enabled = 'yes'; + } elseif ('html' === $enabled) { + $enabled = 'html'; + } else { + $enabled = 'no'; + } + + return $enabled; + } +} diff --git a/src/Mailgun/Message/README.md b/src/Mailgun/Message/README.md new file mode 100644 index 0000000..b24fb94 --- /dev/null +++ b/src/Mailgun/Message/README.md @@ -0,0 +1,84 @@ +Mailgun - Messages +================== + +This is the Mailgun PHP *Message* utilities. + +The below assumes you've already installed the Mailgun PHP SDK in to your +project. If not, go back to the master README for instructions. + +There are two utilities included, `MessageBuilder` and `BatchMessage`. + +* `MessageBuilder`: Allows you to build a message object by calling methods for +each MIME attribute. +* `BatchMessage`: Extends `MessageBuilder` and allows you to iterate through +recipients from a list. Messages will fire after the 1,000th recipient has been +added. + +Usage - Message Builder +----------------------- +Here's how to use Message Builder to build your Message. + +```php +# Next, instantiate a Message Builder object from the SDK. +$builder = new MessageBuilder(); + +# Define the from address. +$builder->setFromAddress("me@example.com", array("first"=>"PHP", "last" => "SDK")); +# Define a to recipient. +$builder->addToRecipient("john.doe@example.com", array("first" => "John", "last" => "Doe")); +# Define a cc recipient. +$builder->addCcRecipient("sally.doe@example.com", array("full_name" => "Sally Doe")); +# Define the subject. +$builder->setSubject("A message from the PHP SDK using Message Builder!"); +# Define the body of the message. +$builder->setTextBody("This is the text body of the message!"); + +# Other Optional Parameters. +$builder->addCampaignId("My-Awesome-Campaign"); +$builder->addCustomHeader("Customer-Id", "12345"); +$builder->addAttachment("@/tron.jpg"); +$builder->setDeliveryTime("tomorrow 8:00AM", "PST"); +$builder->setClickTracking(true); + +# Finally, send the message. +$mg = Mailgun::create('key-example'); +$domain = ; +$mg->messages()->send("example.com", $builder->getMessage()); +``` + +Usage - Batch Message +--------------------- +Here's how to use Batch Message to easily handle batch sending jobs. + +```php +# First, instantiate the SDK with your API credentials and define your domain. +$mg = new Mailgun("key-example"); + +# Next, instantiate a Message Builder object from the SDK, pass in your sending domain. +$batchMessage = $mg->messages()->getBatchMessage("example.com"); + +# Define the from address. +$batchMessage->setFromAddress("me@example.com", array("first"=>"PHP", "last" => "SDK")); +# Define the subject. +$batchMessage->setSubject("A Batch Message from the PHP SDK!"); +# Define the body of the message. +$batchMessage->setTextBody("This is the text body of the message!"); + +# Next, let's add a few recipients to the batch job. +$batchMessage->addToRecipient("john.doe@example.com", array("first" => "John", "last" => "Doe")); +$batchMessage->addToRecipient("sally.doe@example.com", array("first" => "Sally", "last" => "Doe")); +$batchMessage->addToRecipient("mike.jones@example.com", array("first" => "Mike", "last" => "Jones")); +... +// After 1,000 recipients, Batch Message will automatically post your message to the messages endpoint. + +// Call finalize() to send any remaining recipients still in the buffer. +$batchMessage->finalize(); + +$messageIds = $batchMessage->getMessageIds(); + +``` + +More Documentation +------------------ +See the official [Mailgun Docs](http://documentation.mailgun.com/api-sending.html) +for more information. diff --git a/src/Mailgun/Messages/BatchMessage.php b/src/Mailgun/Messages/BatchMessage.php index 0788c56..e3e432f 100644 --- a/src/Mailgun/Messages/BatchMessage.php +++ b/src/Mailgun/Messages/BatchMessage.php @@ -18,6 +18,7 @@ use Mailgun\Messages\Exceptions\TooManyParameters; * This class is used for batch sending. See the official documentation (link below) * for usage instructions. * + * @deprecated Will be removed in 3.0. Use Mailgun\Message\BatchMessage * @see https://github.com/mailgun/mailgun-php/blob/master/src/Mailgun/Messages/README.md */ class BatchMessage extends MessageBuilder diff --git a/src/Mailgun/Messages/MessageBuilder.php b/src/Mailgun/Messages/MessageBuilder.php index 7e07f26..11db740 100644 --- a/src/Mailgun/Messages/MessageBuilder.php +++ b/src/Mailgun/Messages/MessageBuilder.php @@ -20,6 +20,7 @@ use Mailgun\Messages\Exceptions\TooManyParameters; * this class makes the process easier. See the official * documentation (link below) for usage instructions. * + * @deprecated Will be removed in 3.0. Use Mailgun\Message\MessageBuilder * @see https://github.com/mailgun/mailgun-php/blob/master/src/Mailgun/Messages/README.md */ class MessageBuilder diff --git a/tests/Message/BatchMessageTest.php b/tests/Message/BatchMessageTest.php new file mode 100644 index 0000000..7c381fa --- /dev/null +++ b/tests/Message/BatchMessageTest.php @@ -0,0 +1,179 @@ +getMockBuilder(Message::class) + ->disableOriginalConstructor() + ->setMethods(['send', 'sendMime', 'show']) + ->getMock(); + $messageApi->method('send') + ->willReturn(SendResponse::create(['id' => 4711, 'message' => 'Message sent'])); + + $this->batchMessage = $messageApi->getBatchMessage('example.com'); + } + + public function testAddRecipient() + { + $this->batchMessage->addToRecipient('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = NSA::getProperty($this->batchMessage, 'message'); + $this->assertEquals(['to' => ['"Test User" ']], $message); + + $counter = NSA::getProperty($this->batchMessage, 'counters'); + $this->assertEquals(1, $counter['recipients']['to']); + } + + public function testAddRecipientWithoutFirstAndLastName() + { + $this->batchMessage->addToRecipient('test@samples.mailgun.org'); + $message = NSA::getProperty($this->batchMessage, 'message'); + $this->assertEquals(['to' => ['test@samples.mailgun.org']], $message); + + $counter = NSA::getProperty($this->batchMessage, 'counters'); + $this->assertEquals(1, $counter['recipients']['to']); + } + + public function testRecipientVariablesOnTo() + { + $this->batchMessage->addToRecipient('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = NSA::getProperty($this->batchMessage, 'message'); + $this->assertEquals(['to' => ['"Test User" ']], $message); + + $attributes = NSA::getProperty($this->batchMessage, 'batchRecipientAttributes'); + $this->assertEquals('Test', $attributes['test@samples.mailgun.org']['first']); + $this->assertEquals('User', $attributes['test@samples.mailgun.org']['last']); + } + + public function testRecipientVariablesOnCc() + { + $this->batchMessage->addCcRecipient('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = NSA::getProperty($this->batchMessage, 'message'); + $this->assertEquals(['cc' => ['"Test User" ']], $message); + + $attributes = NSA::getProperty($this->batchMessage, 'batchRecipientAttributes'); + $this->assertEquals('Test', $attributes['test@samples.mailgun.org']['first']); + $this->assertEquals('User', $attributes['test@samples.mailgun.org']['last']); + } + + public function testRecipientVariablesOnBcc() + { + $this->batchMessage->addBccRecipient('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = NSA::getProperty($this->batchMessage, 'message'); + $this->assertEquals(['bcc' => ['"Test User" ']], $message); + + $attributes = NSA::getProperty($this->batchMessage, 'batchRecipientAttributes'); + $this->assertEquals('Test', $attributes['test@samples.mailgun.org']['first']); + $this->assertEquals('User', $attributes['test@samples.mailgun.org']['last']); + } + + public function testAddMultipleBatchRecipients() + { + for ($i = 0; $i < 100; ++$i) { + $this->batchMessage->addToRecipient("$i@samples.mailgun.org", ['first' => 'Test', 'last' => "User $i"]); + } + $message = NSA::getProperty($this->batchMessage, 'message'); + $this->assertEquals(100, count($message['to'])); + } + + public function testMaximumBatchSize() + { + $this->batchMessage->setFromAddress('samples@mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setSubject('This is the subject of the message!'); + $this->batchMessage->setTextBody('This is the text body of the message!'); + for ($i = 0; $i < 1001; ++$i) { + $this->batchMessage->addToRecipient("$i@samples.mailgun.org", ['first' => 'Test', 'last' => "User $i"]); + } + $message = NSA::getProperty($this->batchMessage, 'message'); + $this->assertEquals(1, count($message['to'])); + } + + public function testAttributeResetOnEndBatchMessage() + { + $this->batchMessage->addToRecipient('test-user@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setFromAddress('samples@mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setSubject('This is the subject of the message!'); + $this->batchMessage->setTextBody('This is the text body of the message!'); + $this->batchMessage->finalize(); + $message = NSA::getProperty($this->batchMessage, 'message'); + $this->assertTrue(true, empty($message)); + } + + public function testDefaultIDInVariables() + { + $this->batchMessage->addToRecipient('test-to@samples.mailgun.org'); + $this->batchMessage->addCcRecipient('test-cc@samples.mailgun.org'); + + $attributes = NSA::getProperty($this->batchMessage, 'batchRecipientAttributes'); + $this->assertEquals('to_1', $attributes['test-to@samples.mailgun.org']['id']); + $this->assertEquals('cc_1', $attributes['test-cc@samples.mailgun.org']['id']); + } + + public function testGetMessageIds() + { + $this->batchMessage->addToRecipient('test-user@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setFromAddress('samples@mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setSubject('This is the subject of the message!'); + $this->batchMessage->setTextBody('This is the text body of the message!'); + $this->batchMessage->finalize(); + + $this->assertEquals(['4711'], $this->batchMessage->getMessageIds()); + } + + public function testInvalidMissingRequiredMIMEParametersExceptionGetsFlungNoFrom() + { + $this->batchMessage->addToRecipient('test-user@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setSubject('This is the subject of the message!'); + $this->batchMessage->setTextBody('This is the text body of the message!'); + + $this->setExpectedException(MissingRequiredParameter::class); + $this->batchMessage->finalize(); + } + + public function testInvalidMissingRequiredMIMEParametersExceptionGetsFlungNoTo() + { + $this->batchMessage->setFromAddress('samples@mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setSubject('This is the subject of the message!'); + $this->batchMessage->setTextBody('This is the text body of the message!'); + $this->setExpectedException(MissingRequiredParameter::class); + $this->batchMessage->finalize(); + } + + public function testInvalidMissingRequiredMIMEParametersExceptionGetsFlungNoSubject() + { + $this->batchMessage->addToRecipient('test-user@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setFromAddress('samples@mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setTextBody('This is the text body of the message!'); + $this->setExpectedException(MissingRequiredParameter::class); + $this->batchMessage->finalize(); + } + + public function testInvalidMissingRequiredMIMEParametersExceptionGetsFlungNoTextOrHtml() + { + $this->batchMessage->addToRecipient('test-user@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setFromAddress('samples@mailgun.org', ['first' => 'Test', 'last' => 'User']); + $this->batchMessage->setSubject('This is the subject of the message!'); + $this->setExpectedException(MissingRequiredParameter::class); + $this->batchMessage->finalize(); + } +} diff --git a/tests/Message/MessageBuilderTest.php b/tests/Message/MessageBuilderTest.php new file mode 100644 index 0000000..3bfee60 --- /dev/null +++ b/tests/Message/MessageBuilderTest.php @@ -0,0 +1,340 @@ +messageBuilder = new MessageBuilder(); + } + + public function testBlankInstantiation() + { + $message = $this->messageBuilder->getMessage(); + $this->assertTrue(is_array($message)); + } + + public function testCountersSetToZero() + { + $counters = NSA::getProperty($this->messageBuilder, 'counters'); + $this->assertEquals(0, $counters['recipients']['to']); + $this->assertEquals(0, $counters['recipients']['cc']); + $this->assertEquals(0, $counters['recipients']['bcc']); + $this->assertEquals(0, $counters['attributes']['attachment']); + $this->assertEquals(0, $counters['attributes']['campaign_id']); + $this->assertEquals(0, $counters['attributes']['custom_option']); + $this->assertEquals(0, $counters['attributes']['tag']); + } + + public function testAddToRecipient() + { + $this->messageBuilder->addToRecipient('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['to' => ['"Test User" ']], $message); + } + + public function testAddCcRecipient() + { + $this->messageBuilder->addCcRecipient('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['cc' => ['"Test User" ']], $message); + } + + public function testAddBccRecipient() + { + $this->messageBuilder->addBccRecipient('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['bcc' => ['"Test User" ']], $message); + } + + public function testToRecipientCount() + { + $this->messageBuilder->addToRecipient('test-user@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + + $array = NSA::getProperty($this->messageBuilder, 'counters'); + $this->assertEquals(1, $array['recipients']['to']); + } + + public function testCcRecipientCount() + { + $this->messageBuilder->addCcRecipient('test-user@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + + $array = NSA::getProperty($this->messageBuilder, 'counters'); + $this->assertEquals(1, $array['recipients']['cc']); + } + + public function testBccRecipientCount() + { + $this->messageBuilder->addBccRecipient('test-user@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + + $array = NSA::getProperty($this->messageBuilder, 'counters'); + $this->assertEquals(1, $array['recipients']['bcc']); + } + + public function testSetFromAddress() + { + $this->messageBuilder->setFromAddress('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['from' => ['"Test User" ']], $message); + } + + public function testSetReplyTo() + { + $this->messageBuilder->setReplyToAddress('overwritten@samples.mailgun.org'); + $this->messageBuilder->setReplyToAddress('test@samples.mailgun.org', ['first' => 'Test', 'last' => 'User']); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['h:reply-to' => '"Test User" '], $message); + } + + public function testSetSubject() + { + $this->messageBuilder->setSubject('Test Subject'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['subject' => 'Test Subject'], $message); + } + + public function testAddCustomHeader() + { + $this->messageBuilder->addCustomHeader('My-Header', '123'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['h:My-Header' => '123'], $message); + } + + public function testAddMultipleCustomHeader() + { + $this->messageBuilder->addCustomHeader('My-Header', '123'); + $this->messageBuilder->addCustomHeader('My-Header', '456'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['h:My-Header' => ['123', '456']], $message); + } + + public function testSetTextBody() + { + $this->messageBuilder->setTextBody('This is the text body!'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['text' => 'This is the text body!'], $message); + } + + public function testSetHtmlBody() + { + $this->messageBuilder->setHtmlBody('This is an awesome email'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['html' => 'This is an awesome email'], $message); + } + + public function testAddAttachments() + { + $this->messageBuilder->addAttachment('@../TestAssets/mailgun_icon.png'); + $this->messageBuilder->addAttachment('@../TestAssets/rackspace_logo.png'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals( + [ + [ + 'filePath' => '@../TestAssets/mailgun_icon.png', + 'remoteName' => null, + ], + [ + 'filePath' => '@../TestAssets/rackspace_logo.png', + 'remoteName' => null, + ], + ], + $message['attachment'] + ); + } + + public function testAddInlineImages() + { + $this->messageBuilder->addInlineImage('@../TestAssets/mailgun_icon.png'); + $this->messageBuilder->addInlineImage('@../TestAssets/rackspace_logo.png'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals( + [ + [ + 'filePath' => '@../TestAssets/mailgun_icon.png', + 'remoteName' => null, + ], + [ + 'filePath' => '@../TestAssets/rackspace_logo.png', + 'remoteName' => null, + ], + ], + $message['inline'] + ); + } + + public function testAddAttachmentsPostName() + { + $this->messageBuilder->addAttachment('@../TestAssets/mailgun_icon.png', 'mg_icon.png'); + $this->messageBuilder->addAttachment('@../TestAssets/rackspace_logo.png', 'rs_logo.png'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals( + [ + [ + 'filePath' => '@../TestAssets/mailgun_icon.png', + 'remoteName' => 'mg_icon.png', + ], + [ + 'filePath' => '@../TestAssets/rackspace_logo.png', + 'remoteName' => 'rs_logo.png', + ], + ], + $message['attachment'] + ); + } + + public function testAddInlineImagePostName() + { + $this->messageBuilder->addInlineImage('@../TestAssets/mailgun_icon.png', 'mg_icon.png'); + $this->messageBuilder->addInlineImage('@../TestAssets/rackspace_logo.png', 'rs_logo.png'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals( + [ + [ + 'filePath' => '@../TestAssets/mailgun_icon.png', + 'remoteName' => 'mg_icon.png', + ], + [ + 'filePath' => '@../TestAssets/rackspace_logo.png', + 'remoteName' => 'rs_logo.png', + ], + ], + $message['inline'] + ); + } + + public function testSetTestMode() + { + $this->messageBuilder->setTestMode(true); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:testmode' => 'yes'], $message); + $this->messageBuilder->setTestMode(false); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:testmode' => 'no'], $message); + $this->messageBuilder->setTestMode('yes'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:testmode' => 'yes'], $message); + $this->messageBuilder->setTestMode('no'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:testmode' => 'no'], $message); + } + + public function testAddCampaignId() + { + $this->messageBuilder->addCampaignId('ABC123'); + $this->messageBuilder->addCampaignId('XYZ987'); + $this->messageBuilder->addCampaignId('TUV456'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:campaign' => ['ABC123', 'XYZ987', 'TUV456']], $message); + } + + public function testAddCampaignIdInteger() + { + $this->messageBuilder->addCampaignId(1111); + $this->messageBuilder->addCampaignId(2222); + $message = $this->messageBuilder->getMessage(); + $this->assertSame(['o:campaign' => ['1111', '2222']], $message); + } + + public function testSetDkim() + { + $this->messageBuilder->setDkim(true); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:dkim' => 'yes'], $message); + $this->messageBuilder->setDkim(false); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:dkim' => 'no'], $message); + $this->messageBuilder->setDkim('yes'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:dkim' => 'yes'], $message); + $this->messageBuilder->setDkim('no'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:dkim' => 'no'], $message); + } + + public function testSetClickTracking() + { + $this->messageBuilder->setClickTracking(true); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:tracking-clicks' => 'yes'], $message); + $this->messageBuilder->setClickTracking(false); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:tracking-clicks' => 'no'], $message); + $this->messageBuilder->setClickTracking('yes'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:tracking-clicks' => 'yes'], $message); + $this->messageBuilder->setClickTracking('no'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:tracking-clicks' => 'no'], $message); + } + + public function testSetOpenTracking() + { + $this->messageBuilder->setOpenTracking(true); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:tracking-opens' => 'yes'], $message); + $this->messageBuilder->setOpenTracking(false); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:tracking-opens' => 'no'], $message); + $this->messageBuilder->setOpenTracking('yes'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:tracking-opens' => 'yes'], $message); + $this->messageBuilder->setOpenTracking('no'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:tracking-opens' => 'no'], $message); + } + + public function testSetDeliveryTime() + { + $this->messageBuilder->setDeliveryTime('January 15, 2014 8:00AM', 'CST'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:deliverytime' => 'Wed, 15 Jan 2014 08:00:00 -0600'], $message); + $this->messageBuilder->setDeliveryTime('January 15, 2014 8:00AM', 'UTC'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:deliverytime' => 'Wed, 15 Jan 2014 08:00:00 +0000'], $message); + $this->messageBuilder->setDeliveryTime('January 15, 2014 8:00AM'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:deliverytime' => 'Wed, 15 Jan 2014 08:00:00 +0000'], $message); + $this->messageBuilder->setDeliveryTime('1/15/2014 13:50:01', 'CDT'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['o:deliverytime' => 'Wed, 15 Jan 2014 13:50:01 -0600'], $message); + } + + public function testAddCustomData() + { + $this->messageBuilder->addCustomData('My-Super-Awesome-Data', ['What' => 'Mailgun Rocks!']); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['v:My-Super-Awesome-Data' => '{"What":"Mailgun Rocks!"}'], $message); + } + + public function testAddCustomParameter() + { + $this->messageBuilder->addCustomParameter('my-option', 'yes'); + $this->messageBuilder->addCustomParameter('o:my-other-option', 'no'); + $message = $this->messageBuilder->getMessage(); + $this->assertEquals(['my-option' => ['yes'], 'o:my-other-option' => ['no']], $message); + } + + public function testSetMessage() + { + $message = [1, 2, 3, 4, 5]; + $this->messageBuilder->setMessage($message); + + $this->assertEquals($message, $this->messageBuilder->getMessage()); + } +} diff --git a/tests/Messages/ComplexMessageTest.php b/tests/Messages/ComplexMessageTest.php index af60270..f538f80 100644 --- a/tests/Messages/ComplexMessageTest.php +++ b/tests/Messages/ComplexMessageTest.php @@ -9,6 +9,7 @@ namespace Mailgun\Tests\Messages; +use Http\Client\HttpClient; use Mailgun\Connection\RestClient; use Mailgun\Tests\Mock\Mailgun;