This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Kinglozzer\SilverStripeMailgunner\Tests; |
||
4 | |||
5 | use Kinglozzer\SilverStripeMailgunner\Mailer; |
||
6 | use Config; |
||
7 | use Email; |
||
8 | use Injector; |
||
9 | |||
10 | class MailerTest extends \SapphireTest |
||
11 | { |
||
12 | /** |
||
13 | * @param object &$object |
||
14 | * @param string $methodName |
||
15 | * @param array $parameters |
||
16 | * @return mixed |
||
17 | */ |
||
18 | protected function invokeMethod(&$object, $methodName, array $parameters = []) |
||
19 | { |
||
20 | $reflection = new \ReflectionClass(get_class($object)); |
||
21 | $method = $reflection->getMethod($methodName); |
||
22 | $method->setAccessible(true); |
||
23 | |||
24 | return $method->invokeArgs($object, $parameters); |
||
25 | } |
||
26 | |||
27 | /** |
||
28 | * Simple test to check that registering the mailer as an Injector service |
||
29 | * will make it the default mailer used by Email |
||
30 | */ |
||
31 | public function testMailerRegistrationWithEmail() |
||
32 | { |
||
33 | Injector::nest(); |
||
34 | Injector::inst()->registerService(new Mailer, 'Mailer'); |
||
35 | $this->assertInstanceOf('Kinglozzer\SilverStripeMailgunner\Mailer', Email::mailer()); |
||
36 | |||
37 | Injector::unnest(); |
||
38 | $this->assertNotInstanceOf('Kinglozzer\SilverStripeMailgunner\Mailer', Email::mailer()); |
||
39 | } |
||
40 | |||
41 | public function testSetGetMailgunClient() |
||
42 | { |
||
43 | $mailer = new Mailer; |
||
44 | $mockClient = $this->getMock('Mailgun\Mailgun'); |
||
45 | |||
46 | $this->assertInstanceOf('Mailgun\Mailgun', $mailer->getMailgunClient()); |
||
47 | |||
48 | $mailer->setMailgunClient($mockClient); |
||
49 | $this->assertSame($mockClient, $mailer->getMailgunClient()); |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * @return array |
||
54 | */ |
||
55 | protected function getMockEmail() |
||
56 | { |
||
57 | return [ |
||
58 | '"Foo Smith" <[email protected]>', // to |
||
59 | '"Baz Smith" <[email protected]>', // from |
||
60 | 'Important question', // subject |
||
61 | '<p>How much foo could a foo bar baz if a baz bam could bar foo?</p>', // html content |
||
62 | 'How much foo could a foo bar baz if a baz bam could bar foo?', // plain text content |
||
63 | [ |
||
64 | [ |
||
65 | 'filename' => 'filename.jpg', |
||
66 | 'contents' => 'abcdefg' |
||
67 | ] |
||
68 | ], // attachments |
||
69 | [ |
||
70 | 'X-Custom-Header' => 'foo', |
||
71 | 'Cc' => '[email protected]', |
||
72 | 'Bcc' => '[email protected]' |
||
73 | ] // headers |
||
74 | ]; |
||
75 | } |
||
76 | |||
77 | View Code Duplication | public function testSendPlain() |
|
0 ignored issues
–
show
|
|||
78 | { |
||
79 | list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); |
||
80 | |||
81 | $mailer = $this->getMock('Kinglozzer\SilverStripeMailgunner\Mailer', ['sendMessage']); |
||
82 | $mailer->expects($this->once()) |
||
83 | ->method('sendMessage') |
||
84 | ->with( |
||
85 | $this->equalTo($to), |
||
86 | $this->equalTo($from), |
||
87 | $this->equalTo($subject), |
||
88 | $this->equalTo(''), |
||
89 | $this->equalTo($plainContent), |
||
90 | $this->equalTo($attachments), |
||
91 | $this->equalTo($headers) |
||
92 | ); |
||
93 | |||
94 | $mailer->sendPlain($to, $from, $subject, $plainContent, $attachments, $headers); |
||
95 | } |
||
96 | |||
97 | View Code Duplication | public function testSendHTML() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
98 | { |
||
99 | list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); |
||
100 | |||
101 | $mailer = $this->getMock('Kinglozzer\SilverStripeMailgunner\Mailer', ['sendMessage']); |
||
102 | $mailer->expects($this->once()) |
||
103 | ->method('sendMessage') |
||
104 | ->with( |
||
105 | $this->equalTo($to), |
||
106 | $this->equalTo($from), |
||
107 | $this->equalTo($subject), |
||
108 | $this->equalTo($content), |
||
109 | $this->equalTo($plainContent), |
||
110 | $this->equalTo($attachments), |
||
111 | $this->equalTo($headers) |
||
112 | ); |
||
113 | |||
114 | $mailer->sendHTML($to, $from, $subject, $content, $attachments, $headers, $plainContent); |
||
115 | } |
||
116 | |||
117 | public function testSendMessage() |
||
118 | { |
||
119 | $domain = 'http://testdomain.com'; |
||
120 | Config::inst()->update('Kinglozzer\SilverStripeMailgunner\Mailer', 'api_domain', $domain); |
||
121 | |||
122 | list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); |
||
123 | $preparedattachments = [ |
||
124 | ['filePath' => '/foo/bar/baz', 'remoteName' => 'image.jpg'] |
||
125 | ]; |
||
126 | |||
127 | $messageBuilder = $this->getMock('Mailgun\Messages\MessageBuilder', ['getMessage', 'getFiles']); |
||
128 | // We expect that sendMessage() will fetch the full message text from the builder |
||
129 | $messageBuilder->expects($this->once()) |
||
130 | ->method('getMessage') |
||
131 | ->will($this->returnValue('test message')); |
||
132 | $messageBuilder->expects($this->once()) |
||
133 | ->method('getFiles') |
||
134 | ->will($this->returnValue('attachedfiles')); |
||
135 | |||
136 | $client = $this->getMock('Mailgun\Mailgun', ['MessageBuilder', 'sendMessage']); |
||
137 | // We expect that sendMessage() will fetch the message builder from the Mailgun client, and |
||
138 | // we use this point to inject our mock message builder |
||
139 | $client->expects($this->once()) |
||
140 | ->method('MessageBuilder') |
||
141 | ->will($this->returnValue($messageBuilder)); |
||
142 | // We expect that Mailer::sendMessage() will trigger Mailgun::sendMessage() with the |
||
143 | // domain set in config, and the prepared message and attachments |
||
144 | $client->expects($this->once()) |
||
145 | ->method('sendMessage') |
||
146 | ->with( |
||
147 | $this->equalTo($domain), |
||
148 | $this->equalTo('test message'), |
||
149 | $this->equalTo('attachedfiles') |
||
150 | ); |
||
151 | |||
152 | $mailer = $this->getMock( |
||
153 | 'Kinglozzer\SilverStripeMailgunner\Mailer', |
||
154 | ['getMailgunClient', 'buildMessage', 'prepareAttachments', 'closeTempFileHandles'] |
||
155 | ); |
||
156 | // We inject our mock Mailgun client while asserting that sendMessage() does request it |
||
157 | $mailer->expects($this->once()) |
||
158 | ->method('getMailgunClient') |
||
159 | ->will($this->returnValue($client)); |
||
160 | // We've got attachments, so we assert that sendMessage() passes them off to |
||
161 | // prepareAttachments() and specify a mock "prepared" return value |
||
162 | $mailer->expects($this->once()) |
||
163 | ->method('prepareAttachments') |
||
164 | ->with($this->equalTo($attachments)) |
||
165 | ->will($this->returnValue($preparedattachments)); |
||
166 | // We expect that sendMessage() will pass everything off to the buildMessage() method |
||
167 | $mailer->expects($this->once()) |
||
168 | ->method('buildMessage') |
||
169 | ->with( |
||
170 | $this->equalTo($messageBuilder), |
||
171 | $this->equalTo($to), |
||
172 | $this->equalTo($from), |
||
173 | $this->equalTo($subject), |
||
174 | $this->equalTo($content), |
||
175 | $this->equalTo($plainContent), |
||
176 | $this->equalTo($preparedattachments), |
||
177 | $this->equalTo($headers) |
||
178 | ); |
||
179 | // Assert that the mailer attempts to close any remaining open file handles |
||
180 | $mailer->expects($this->once()) |
||
181 | ->method('closeTempFileHandles'); |
||
182 | |||
183 | // Let's go! |
||
184 | $this->invokeMethod( |
||
185 | $mailer, |
||
186 | 'sendMessage', |
||
187 | [$to, $from, $subject, $content, $plainContent, $attachments, $headers] |
||
188 | ); |
||
189 | } |
||
190 | |||
191 | public function testSendMessageBatch() |
||
192 | { |
||
193 | $domain = 'http://testdomain.com'; |
||
194 | Config::inst()->update('Kinglozzer\SilverStripeMailgunner\Mailer', 'api_domain', $domain); |
||
195 | list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); |
||
196 | |||
197 | $preparedattachments = [ |
||
198 | ['filePath' => '/foo/bar/baz', 'remoteName' => 'image.jpg'] |
||
199 | ]; |
||
200 | |||
201 | $messageBuilder = $this->getMockBuilder('Mailgun\Messages\BatchMessage') |
||
202 | ->disableOriginalConstructor() |
||
203 | ->setMethods(['finalize']) |
||
204 | ->getMock(); |
||
205 | // We expect that finalize() will be called to send any remaining messages in the queue |
||
206 | $messageBuilder->expects($this->once()) |
||
207 | ->method('finalize'); |
||
208 | |||
209 | $client = $this->getMock('Mailgun\Mailgun', ['BatchMessage']); |
||
210 | // We expect that sendMessage() will fetch the message builder from the Mailgun client, and |
||
211 | // we use this point to inject our mock message builder |
||
212 | $client->expects($this->once()) |
||
213 | ->method('BatchMessage') |
||
214 | ->with($this->equalTo($domain)) |
||
215 | ->will($this->returnValue($messageBuilder)); |
||
216 | |||
217 | $mailer = $this->getMock( |
||
218 | 'Kinglozzer\SilverStripeMailgunner\Mailer', |
||
219 | ['getMailgunClient', 'buildMessage', 'prepareAttachments', 'closeTempFileHandles'] |
||
220 | ); |
||
221 | // We inject our mock Mailgun client while asserting that sendMessage() does request it |
||
222 | $mailer->expects($this->once()) |
||
223 | ->method('getMailgunClient') |
||
224 | ->will($this->returnValue($client)); |
||
225 | // We've got attachments, so we assert that sendMessage() passes them off to |
||
226 | // prepareAttachments() and specify a mock "prepared" return value |
||
227 | $mailer->expects($this->once()) |
||
228 | ->method('prepareAttachments') |
||
229 | ->with($this->equalTo($attachments)) |
||
230 | ->will($this->returnValue($preparedattachments)); |
||
231 | // We expect that sendMessage() will pass everything off to the buildMessage() method |
||
232 | $mailer->expects($this->once()) |
||
233 | ->method('buildMessage') |
||
234 | ->with( |
||
235 | $this->equalTo($messageBuilder), |
||
236 | $this->equalTo($to), |
||
237 | $this->equalTo($from), |
||
238 | $this->equalTo($subject), |
||
239 | $this->equalTo($content), |
||
240 | $this->equalTo($plainContent), |
||
241 | $this->equalTo($preparedattachments), |
||
242 | $this->equalTo($headers) |
||
243 | ); |
||
244 | // Assert that the mailer attempts to close any remaining open file handles |
||
245 | $mailer->expects($this->once()) |
||
246 | ->method('closeTempFileHandles'); |
||
247 | |||
248 | // Special header to flag that we want to send a "batch message" |
||
249 | $headers['X-Mailgunner-Batch-Message'] = true; |
||
250 | |||
251 | // Let's go! |
||
252 | $this->invokeMethod( |
||
253 | $mailer, |
||
254 | 'sendMessage', |
||
255 | [$to, $from, $subject, $content, $plainContent, $attachments, $headers] |
||
256 | ); |
||
257 | } |
||
258 | |||
259 | public function testSendMessageExceptionClosesHandles() |
||
260 | { |
||
261 | list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); |
||
262 | |||
263 | $client = $this->getMock('Mailgun\Mailgun', ['sendMessage']); |
||
264 | // Make our mock client trigger an exception |
||
265 | $client->expects($this->once()) |
||
266 | ->method('sendMessage') |
||
267 | ->will($this->throwException(new \Exception)); |
||
268 | |||
269 | $mailer = $this->getMock( |
||
270 | 'Kinglozzer\SilverStripeMailgunner\Mailer', |
||
271 | ['getMailgunClient', 'closeTempFileHandles'] |
||
272 | ); |
||
273 | // Inject our mock Mailgun client |
||
274 | $mailer->expects($this->once()) |
||
275 | ->method('getMailgunClient') |
||
276 | ->will($this->returnValue($client)); |
||
277 | // Assert that the exception that the client throws triggers closing open file handles |
||
278 | $mailer->expects($this->once()) |
||
279 | ->method('closeTempFileHandles'); |
||
280 | |||
281 | $response = $this->invokeMethod( |
||
282 | $mailer, |
||
283 | 'sendMessage', |
||
284 | [$to, $from, $subject, $content, $plainContent, $attachments, $headers] |
||
285 | ); |
||
286 | |||
287 | $this->assertFalse($response); |
||
288 | } |
||
289 | |||
290 | public function testBuildMessage() |
||
291 | { |
||
292 | list($to, $from, $subject, $content, $plainContent, $attachments, $headers) = $this->getMockEmail(); |
||
293 | // Mock "prepared" attachment |
||
294 | $attachments = [ |
||
295 | ['filePath' => '/foo/bar/baz', 'remoteName' => 'image.jpg'] |
||
296 | ]; |
||
297 | |||
298 | $messageBuilder = $this->getMock('Mailgun\Messages\MessageBuilder'); |
||
299 | $messageBuilder->expects($this->once()) |
||
300 | ->method('addToRecipient') |
||
301 | ->with( |
||
302 | $this->equalTo('[email protected]'), |
||
303 | $this->equalTo(['full_name' => 'Foo Smith']) |
||
304 | ); |
||
305 | |||
306 | $messageBuilder->expects($this->once()) |
||
307 | ->method('setFromAddress') |
||
308 | ->with( |
||
309 | $this->equalTo('[email protected]'), |
||
310 | $this->equalTo(['full_name' => 'Baz Smith']) |
||
311 | ); |
||
312 | |||
313 | $messageBuilder->expects($this->once()) |
||
314 | ->method('setSubject') |
||
315 | ->with($this->equalTo($subject)); |
||
316 | |||
317 | $messageBuilder->expects($this->once()) |
||
318 | ->method('setHtmlBody') |
||
319 | ->with($this->equalTo($content)); |
||
320 | |||
321 | $messageBuilder->expects($this->once()) |
||
322 | ->method('setTextBody') |
||
323 | ->with($this->equalTo($plainContent)); |
||
324 | |||
325 | $messageBuilder->expects($this->once()) |
||
326 | ->method('addAttachment') |
||
327 | ->with( |
||
328 | $this->equalTo('/foo/bar/baz'), |
||
329 | $this->equalTo('image.jpg') |
||
330 | ); |
||
331 | |||
332 | $messageBuilder->expects($this->once()) |
||
333 | ->method('addCcRecipient') |
||
334 | ->with($this->equalTo($headers['Cc'])); |
||
335 | |||
336 | $messageBuilder->expects($this->once()) |
||
337 | ->method('addBccRecipient') |
||
338 | ->with($this->equalTo($headers['Bcc'])); |
||
339 | |||
340 | $messageBuilder->expects($this->once()) |
||
341 | ->method('addCustomHeader') |
||
342 | ->with( |
||
343 | $this->equalTo('X-Custom-Header'), |
||
344 | $this->equalTo('foo') |
||
345 | ); |
||
346 | |||
347 | $this->invokeMethod( |
||
348 | new Mailer, |
||
349 | 'buildMessage', |
||
350 | [$messageBuilder, $to, $from, $subject, $content, $plainContent, $attachments, $headers] |
||
351 | ); |
||
352 | } |
||
353 | |||
354 | public function testParseAddresses() |
||
355 | { |
||
356 | $mailer = new Mailer; |
||
357 | |||
358 | $parsed = $this->invokeMethod($mailer, 'parseAddresses', ['[email protected]']); |
||
359 | $this->assertEquals(['[email protected]' => ''], $parsed); |
||
360 | |||
361 | $parsed = $this->invokeMethod($mailer, 'parseAddresses', ['Joe Bloggs <[email protected]>']); |
||
362 | $this->assertEquals(['[email protected]' => 'Joe Bloggs'], $parsed); |
||
363 | |||
364 | $parsed = $this->invokeMethod($mailer, 'parseAddresses', ['[email protected], [email protected]']); |
||
365 | $this->assertEquals(['[email protected]' => '', '[email protected]' => ''], $parsed); |
||
366 | |||
367 | // Test all the different formats |
||
368 | $raw = '"Joe Bloggs"<[email protected]>; John Smith <[email protected]>'; |
||
369 | $raw .= ', \'James\'<[email protected]>; [email protected],<[email protected]>'; |
||
370 | $expected = [ |
||
371 | '[email protected]' => 'Joe Bloggs', |
||
372 | '[email protected]' => 'John Smith', |
||
373 | '[email protected]' => 'James', |
||
374 | '[email protected]' => '', |
||
375 | '[email protected]' => '' |
||
376 | ]; |
||
377 | $actual = $this->invokeMethod($mailer, 'parseAddresses', [$raw]); |
||
378 | $this->assertEquals($expected, $actual); |
||
379 | } |
||
380 | |||
381 | public function testPrepareAttachments() |
||
382 | { |
||
383 | $attachments = [ |
||
384 | ['filename' => 'test1.jpg', 'contents' => 'abcdefg'], |
||
385 | ['filename' => 'test2.jpg', 'contents' => 'hijklmn'] |
||
386 | ]; |
||
387 | |||
388 | $expected = [ |
||
389 | ['filePath' => 'tmp/test1.jpg', 'remoteName' => 'test1.jpg'], |
||
390 | ['filePath' => 'tmp/test2.jpg', 'remoteName' => 'test2.jpg'] |
||
391 | ]; |
||
392 | |||
393 | $mailer = $this->getMock('Kinglozzer\SilverStripeMailgunner\Mailer', ['writeToTempFile']); |
||
394 | $mailer->expects($this->at(0)) |
||
395 | ->method('writeToTempFile') |
||
396 | ->with($this->equalTo('abcdefg')) |
||
397 | ->will($this->returnValue('tmp/test1.jpg')); |
||
398 | $mailer->expects($this->at(1)) |
||
399 | ->method('writeToTempFile') |
||
400 | ->with($this->equalTo('hijklmn')) |
||
401 | ->will($this->returnValue('tmp/test2.jpg')); |
||
402 | |||
403 | $prepared = $this->invokeMethod($mailer, 'prepareAttachments', [$attachments]); |
||
404 | $this->assertEquals($expected, $prepared); |
||
405 | } |
||
406 | |||
407 | public function testWriteToTempFile() |
||
408 | { |
||
409 | $contents = 'test file contents'; |
||
410 | $mailer = new Mailer; |
||
411 | $tempFile = $this->invokeMethod($mailer, 'writeToTempFile', [$contents]); |
||
412 | |||
413 | $this->assertEquals($contents, file_get_contents($tempFile)); |
||
414 | |||
415 | // Assert that the stream and temp file path are stored |
||
416 | $reflection = new \ReflectionClass(get_class($mailer)); |
||
417 | $property = $reflection->getProperty('tempFileHandles'); |
||
418 | $property->setAccessible(true); |
||
419 | $fileHandles = $property->getValue($mailer); |
||
420 | |||
421 | $this->assertNotEmpty($fileHandles); |
||
422 | |||
423 | // Test the contents of the stream |
||
424 | $handle = $fileHandles[0]['handle']; |
||
425 | rewind($handle); |
||
426 | $this->assertEquals($contents, fread($handle, filesize($fileHandles[0]['path']))); |
||
427 | $this->assertEquals($tempFile, $fileHandles[0]['path']); |
||
428 | } |
||
429 | |||
430 | public function testCloseTempFileHandles() |
||
431 | { |
||
432 | $mailer = new Mailer; |
||
433 | $tempFile = tempnam(sys_get_temp_dir(), 'SS_MG_TESTS_TMP'); |
||
434 | $fileHandle = fopen($tempFile, 'w'); |
||
435 | fwrite($fileHandle, 'test data'); |
||
436 | $handleData = ['handle' => $fileHandle, 'path' => $tempFile]; |
||
437 | |||
438 | $reflection = new \ReflectionClass(get_class($mailer)); |
||
439 | $property = $reflection->getProperty('tempFileHandles'); |
||
440 | $property->setAccessible(true); |
||
441 | $fileHandles = $property->setValue($mailer, [$handleData]); |
||
442 | |||
443 | $this->invokeMethod($mailer, 'closeTempFileHandles'); |
||
444 | |||
445 | $this->assertEmpty($property->getValue($mailer)); |
||
446 | $this->assertFalse(file_exists($tempFile)); |
||
447 | $this->assertEquals('Unknown', get_resource_type($fileHandle)); |
||
448 | } |
||
449 | } |
||
450 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.