Source of file MailerTest.php
Size: 17,516 Bytes - Last Modified: 2021-12-24T06:19:27+00:00
/var/www/docs.ssmods.com/process/src/tests/MailerTest.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 | <?php namespace Kinglozzer\SilverStripeMailgunner\Tests; use Kinglozzer\SilverStripeMailgunner\Mailer; use Config; use Email; use Injector; class MailerTest extends \SapphireTest { /** * @param object &$object * @param string $methodName * @param array $parameters * @return mixed */ protected function invokeMethod(&$object, $methodName, array $parameters = []) { $reflection = new \ReflectionClass(get_class($object)); $method = $reflection->getMethod($methodName); $method->setAccessible(true); return $method->invokeArgs($object, $parameters); } /** * Simple test to check that registering the mailer as an Injector service * will make it the default mailer used by Email */ public function testMailerRegistrationWithEmail() { Injector::nest(); Injector::inst()->registerService(new Mailer, 'Mailer'); $this->assertInstanceOf('Kinglozzer\SilverStripeMailgunner\Mailer', Email::mailer()); Injector::unnest(); $this->assertNotInstanceOf('Kinglozzer\SilverStripeMailgunner\Mailer', Email::mailer()); } public function testSetGetMailgunClient() { $mailer = new Mailer; $mockClient = $this->getMock('Mailgun\Mailgun'); $this->assertInstanceOf('Mailgun\Mailgun', $mailer->getMailgunClient()); $mailer->setMailgunClient($mockClient); $this->assertSame($mockClient, $mailer->getMailgunClient()); } /** * @return array */ protected function getMockEmail() { return [ '"Foo Smith" <foo@bar.com>', // to '"Baz Smith" <baz@bam.com>', // from 'Important question', // subject '<p>How much foo could a foo bar baz if a baz bam could bar foo?</p>', // html content 'How much foo could a foo bar baz if a baz bam could bar foo?', // plain text content [ [ 'filename' => 'filename.jpg', 'contents' => 'abcdefg' ] ], // attachments [ 'X-Custom-Header' => 'foo', 'Cc' => 'bar@baz.com', 'Bcc' => 'nobodyiswatchingyou@nsa.gov' ] // headers ]; } public function testSendPlain() { list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); $mailer = $this->getMock('Kinglozzer\SilverStripeMailgunner\Mailer', ['sendMessage']); $mailer->expects($this->once()) ->method('sendMessage') ->with( $this->equalTo($to), $this->equalTo($from), $this->equalTo($subject), $this->equalTo(''), $this->equalTo($plainContent), $this->equalTo($attachments), $this->equalTo($headers) ); $mailer->sendPlain($to, $from, $subject, $plainContent, $attachments, $headers); } public function testSendHTML() { list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); $mailer = $this->getMock('Kinglozzer\SilverStripeMailgunner\Mailer', ['sendMessage']); $mailer->expects($this->once()) ->method('sendMessage') ->with( $this->equalTo($to), $this->equalTo($from), $this->equalTo($subject), $this->equalTo($content), $this->equalTo($plainContent), $this->equalTo($attachments), $this->equalTo($headers) ); $mailer->sendHTML($to, $from, $subject, $content, $attachments, $headers, $plainContent); } public function testSendMessage() { $domain = 'http://testdomain.com'; Config::inst()->update('Kinglozzer\SilverStripeMailgunner\Mailer', 'api_domain', $domain); list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); $preparedattachments = [ ['filePath' => '/foo/bar/baz', 'remoteName' => 'image.jpg'] ]; $messageBuilder = $this->getMock('Mailgun\Messages\MessageBuilder', ['getMessage', 'getFiles']); // We expect that sendMessage() will fetch the full message text from the builder $messageBuilder->expects($this->once()) ->method('getMessage') ->will($this->returnValue('test message')); $messageBuilder->expects($this->once()) ->method('getFiles') ->will($this->returnValue('attachedfiles')); $client = $this->getMock('Mailgun\Mailgun', ['MessageBuilder', 'sendMessage']); // We expect that sendMessage() will fetch the message builder from the Mailgun client, and // we use this point to inject our mock message builder $client->expects($this->once()) ->method('MessageBuilder') ->will($this->returnValue($messageBuilder)); // We expect that Mailer::sendMessage() will trigger Mailgun::sendMessage() with the // domain set in config, and the prepared message and attachments $client->expects($this->once()) ->method('sendMessage') ->with( $this->equalTo($domain), $this->equalTo('test message'), $this->equalTo('attachedfiles') ); $mailer = $this->getMock( 'Kinglozzer\SilverStripeMailgunner\Mailer', ['getMailgunClient', 'buildMessage', 'prepareAttachments', 'closeTempFileHandles'] ); // We inject our mock Mailgun client while asserting that sendMessage() does request it $mailer->expects($this->once()) ->method('getMailgunClient') ->will($this->returnValue($client)); // We've got attachments, so we assert that sendMessage() passes them off to // prepareAttachments() and specify a mock "prepared" return value $mailer->expects($this->once()) ->method('prepareAttachments') ->with($this->equalTo($attachments)) ->will($this->returnValue($preparedattachments)); // We expect that sendMessage() will pass everything off to the buildMessage() method $mailer->expects($this->once()) ->method('buildMessage') ->with( $this->equalTo($messageBuilder), $this->equalTo($to), $this->equalTo($from), $this->equalTo($subject), $this->equalTo($content), $this->equalTo($plainContent), $this->equalTo($preparedattachments), $this->equalTo($headers) ); // Assert that the mailer attempts to close any remaining open file handles $mailer->expects($this->once()) ->method('closeTempFileHandles'); // Let's go! $this->invokeMethod( $mailer, 'sendMessage', [$to, $from, $subject, $content, $plainContent, $attachments, $headers] ); } public function testSendMessageBatch() { $domain = 'http://testdomain.com'; Config::inst()->update('Kinglozzer\SilverStripeMailgunner\Mailer', 'api_domain', $domain); list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); $preparedattachments = [ ['filePath' => '/foo/bar/baz', 'remoteName' => 'image.jpg'] ]; $messageBuilder = $this->getMockBuilder('Mailgun\Messages\BatchMessage') ->disableOriginalConstructor() ->setMethods(['finalize']) ->getMock(); // We expect that finalize() will be called to send any remaining messages in the queue $messageBuilder->expects($this->once()) ->method('finalize'); $client = $this->getMock('Mailgun\Mailgun', ['BatchMessage']); // We expect that sendMessage() will fetch the message builder from the Mailgun client, and // we use this point to inject our mock message builder $client->expects($this->once()) ->method('BatchMessage') ->with($this->equalTo($domain)) ->will($this->returnValue($messageBuilder)); $mailer = $this->getMock( 'Kinglozzer\SilverStripeMailgunner\Mailer', ['getMailgunClient', 'buildMessage', 'prepareAttachments', 'closeTempFileHandles'] ); // We inject our mock Mailgun client while asserting that sendMessage() does request it $mailer->expects($this->once()) ->method('getMailgunClient') ->will($this->returnValue($client)); // We've got attachments, so we assert that sendMessage() passes them off to // prepareAttachments() and specify a mock "prepared" return value $mailer->expects($this->once()) ->method('prepareAttachments') ->with($this->equalTo($attachments)) ->will($this->returnValue($preparedattachments)); // We expect that sendMessage() will pass everything off to the buildMessage() method $mailer->expects($this->once()) ->method('buildMessage') ->with( $this->equalTo($messageBuilder), $this->equalTo($to), $this->equalTo($from), $this->equalTo($subject), $this->equalTo($content), $this->equalTo($plainContent), $this->equalTo($preparedattachments), $this->equalTo($headers) ); // Assert that the mailer attempts to close any remaining open file handles $mailer->expects($this->once()) ->method('closeTempFileHandles'); // Special header to flag that we want to send a "batch message" $headers['X-Mailgunner-Batch-Message'] = true; // Let's go! $this->invokeMethod( $mailer, 'sendMessage', [$to, $from, $subject, $content, $plainContent, $attachments, $headers] ); } public function testSendMessageExceptionClosesHandles() { list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); $client = $this->getMock('Mailgun\Mailgun', ['sendMessage']); // Make our mock client trigger an exception $client->expects($this->once()) ->method('sendMessage') ->will($this->throwException(new \Exception)); $mailer = $this->getMock( 'Kinglozzer\SilverStripeMailgunner\Mailer', ['getMailgunClient', 'closeTempFileHandles'] ); // Inject our mock Mailgun client $mailer->expects($this->once()) ->method('getMailgunClient') ->will($this->returnValue($client)); // Assert that the exception that the client throws triggers closing open file handles $mailer->expects($this->once()) ->method('closeTempFileHandles'); $response = $this->invokeMethod( $mailer, 'sendMessage', [$to, $from, $subject, $content, $plainContent, $attachments, $headers] ); $this->assertFalse($response); } public function testBuildMessage() { list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); // Mock "prepared" attachment $attachments = [ ['filePath' => '/foo/bar/baz', 'remoteName' => 'image.jpg'] ]; $messageBuilder = $this->getMock('Mailgun\Messages\MessageBuilder'); $messageBuilder->expects($this->once()) ->method('addToRecipient') ->with( $this->equalTo('foo@bar.com'), $this->equalTo(['full_name' => 'Foo Smith']) ); $messageBuilder->expects($this->once()) ->method('setFromAddress') ->with( $this->equalTo('baz@bam.com'), $this->equalTo(['full_name' => 'Baz Smith']) ); $messageBuilder->expects($this->once()) ->method('setSubject') ->with($this->equalTo($subject)); $messageBuilder->expects($this->once()) ->method('setHtmlBody') ->with($this->equalTo($content)); $messageBuilder->expects($this->once()) ->method('setTextBody') ->with($this->equalTo($plainContent)); $messageBuilder->expects($this->once()) ->method('addAttachment') ->with( $this->equalTo('/foo/bar/baz'), $this->equalTo('image.jpg') ); $messageBuilder->expects($this->once()) ->method('addCcRecipient') ->with($this->equalTo($headers['Cc'])); $messageBuilder->expects($this->once()) ->method('addBccRecipient') ->with($this->equalTo($headers['Bcc'])); $messageBuilder->expects($this->once()) ->method('addCustomHeader') ->with( $this->equalTo('X-Custom-Header'), $this->equalTo('foo') ); $this->invokeMethod( new Mailer, 'buildMessage', [$messageBuilder, $to, $from, $subject, $content, $plainContent, $attachments, $headers] ); } public function testParseAddresses() { $mailer = new Mailer; $parsed = $this->invokeMethod($mailer, 'parseAddresses', ['joe.bloggs@example.com']); $this->assertEquals(['joe.bloggs@example.com' => ''], $parsed); $parsed = $this->invokeMethod($mailer, 'parseAddresses', ['Joe Bloggs <joe.bloggs@example.com>']); $this->assertEquals(['joe.bloggs@example.com' => 'Joe Bloggs'], $parsed); $parsed = $this->invokeMethod($mailer, 'parseAddresses', ['joe.bloggs@example.com, john.smith@example.com']); $this->assertEquals(['joe.bloggs@example.com' => '', 'john.smith@example.com' => ''], $parsed); // Test all the different formats $raw = '"Joe Bloggs"<joe.bloggs@example.com>; John Smith <john.smith@example.com>'; $raw .= ', \'James\'<james@example.com>; foo@example.com,<bar@example.com>'; $expected = [ 'joe.bloggs@example.com' => 'Joe Bloggs', 'john.smith@example.com' => 'John Smith', 'james@example.com' => 'James', 'foo@example.com' => '', 'bar@example.com' => '' ]; $actual = $this->invokeMethod($mailer, 'parseAddresses', [$raw]); $this->assertEquals($expected, $actual); } public function testPrepareAttachments() { $attachments = [ ['filename' => 'test1.jpg', 'contents' => 'abcdefg'], ['filename' => 'test2.jpg', 'contents' => 'hijklmn'] ]; $expected = [ ['filePath' => 'tmp/test1.jpg', 'remoteName' => 'test1.jpg'], ['filePath' => 'tmp/test2.jpg', 'remoteName' => 'test2.jpg'] ]; $mailer = $this->getMock('Kinglozzer\SilverStripeMailgunner\Mailer', ['writeToTempFile']); $mailer->expects($this->at(0)) ->method('writeToTempFile') ->with($this->equalTo('abcdefg')) ->will($this->returnValue('tmp/test1.jpg')); $mailer->expects($this->at(1)) ->method('writeToTempFile') ->with($this->equalTo('hijklmn')) ->will($this->returnValue('tmp/test2.jpg')); $prepared = $this->invokeMethod($mailer, 'prepareAttachments', [$attachments]); $this->assertEquals($expected, $prepared); } public function testWriteToTempFile() { $contents = 'test file contents'; $mailer = new Mailer; $tempFile = $this->invokeMethod($mailer, 'writeToTempFile', [$contents]); $this->assertEquals($contents, file_get_contents($tempFile)); // Assert that the stream and temp file path are stored $reflection = new \ReflectionClass(get_class($mailer)); $property = $reflection->getProperty('tempFileHandles'); $property->setAccessible(true); $fileHandles = $property->getValue($mailer); $this->assertNotEmpty($fileHandles); // Test the contents of the stream $handle = $fileHandles[0]['handle']; rewind($handle); $this->assertEquals($contents, fread($handle, filesize($fileHandles[0]['path']))); $this->assertEquals($tempFile, $fileHandles[0]['path']); } public function testCloseTempFileHandles() { $mailer = new Mailer; $tempFile = tempnam(sys_get_temp_dir(), 'SS_MG_TESTS_TMP'); $fileHandle = fopen($tempFile, 'w'); fwrite($fileHandle, 'test data'); $handleData = ['handle' => $fileHandle, 'path' => $tempFile]; $reflection = new \ReflectionClass(get_class($mailer)); $property = $reflection->getProperty('tempFileHandles'); $property->setAccessible(true); $fileHandles = $property->setValue($mailer, [$handleData]); $this->invokeMethod($mailer, 'closeTempFileHandles'); $this->assertEmpty($property->getValue($mailer)); $this->assertFalse(file_exists($tempFile)); $this->assertEquals('Unknown', get_resource_type($fileHandle)); } } |