1 | <?php |
||||
2 | |||||
3 | namespace Azine\EmailBundle\Tests\Command; |
||||
4 | |||||
5 | use Azine\EmailBundle\Command\ClearAndLogFailedMailsCommand; |
||||
6 | use Symfony\Component\Console\Application; |
||||
7 | use Symfony\Component\Console\Tester\CommandTester; |
||||
8 | use Symfony\Component\DependencyInjection\ContainerInterface; |
||||
9 | use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
||||
10 | use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; |
||||
11 | use Symfony\Component\Finder\Finder; |
||||
12 | |||||
13 | /** |
||||
14 | * @author dominik |
||||
15 | */ |
||||
16 | class ClearAndLogFailedMailsCommandTest extends \PHPUnit\Framework\TestCase |
||||
17 | { |
||||
18 | public function testHelpInfo() |
||||
19 | { |
||||
20 | $command = $this->getCommand(); |
||||
21 | |||||
22 | $display = $command->getHelp(); |
||||
23 | $this->assertContains('Any email-address that still failed, is logged.', $display); |
||||
24 | } |
||||
25 | |||||
26 | public function testSendingFailedMails() |
||||
27 | { |
||||
28 | $command = $this->getCommand(); |
||||
29 | $failedRecipients = array('[email protected]'); |
||||
30 | $count = 2; |
||||
31 | |||||
32 | $this->createFakeFailedMessageFiles($count); |
||||
33 | $command->setContainer($this->getMockSetup($failedRecipients, false, false, $this->exactly($count))); |
||||
34 | |||||
35 | $display = $this->executeCommandAndGetDisplay($command, array('')); |
||||
36 | $this->assertContains("Retrying to send 'subject blabbla' to '[email protected]'", $display); |
||||
37 | $this->assertContains('Sent!', $display); |
||||
38 | } |
||||
39 | |||||
40 | public function testSendingFailedMailsWithDate() |
||||
41 | { |
||||
42 | $command = $this->getCommand(); |
||||
43 | $failedRecipients = array('[email protected]'); |
||||
44 | $count = 4; |
||||
45 | $this->createFakeFailedMessageFiles($count); |
||||
46 | |||||
47 | $command->setContainer($this->getMockSetup($failedRecipients, false, false, $this->exactly($count))); |
||||
48 | |||||
49 | $display = $this->executeCommandAndGetDisplay($command, array('date' => ' > now -1 minute')); |
||||
50 | $this->assertContains("Retrying to send 'subject blabbla' to '[email protected]'", $display); |
||||
51 | $this->assertContains('Sent!', $display); |
||||
52 | } |
||||
53 | |||||
54 | public function testSendingFailedMailsNoMailsFound() |
||||
55 | { |
||||
56 | $command = $this->getCommand(); |
||||
57 | $failedRecipients = array(); |
||||
58 | $command->setContainer($this->getMockSetup($failedRecipients, false, false, $this->never())); |
||||
59 | |||||
60 | $display = $this->executeCommandAndGetDisplay($command, array('')); |
||||
61 | |||||
62 | $this->assertContains('No failed-message-files found', $display); |
||||
63 | } |
||||
64 | |||||
65 | public function testSendingFailedMailsWithoutTransport() |
||||
66 | { |
||||
67 | $command = $this->getCommand(); |
||||
68 | $failedRecipients = array('[email protected]'); |
||||
69 | $command->setContainer($this->getMockSetup($failedRecipients, false, true)); |
||||
70 | |||||
71 | $display = $this->executeCommandAndGetDisplay($command, array('')); |
||||
72 | |||||
73 | $this->assertContains('Could not load transport. Is file-spooling configured in your config.yml for this environment?', $display); |
||||
74 | } |
||||
75 | |||||
76 | public function testSendingFailedMailsWithoutSpooling() |
||||
77 | { |
||||
78 | $command = $this->getCommand(); |
||||
79 | $failedRecipients = array('[email protected]'); |
||||
80 | $command->setContainer($this->getMockSetup($failedRecipients, true)); |
||||
81 | |||||
82 | $display = $this->executeCommandAndGetDisplay($command, array('')); |
||||
83 | |||||
84 | $this->assertContains('Could not find file spool path. Is file-spooling configured in your config.yml for this environment?', $display); |
||||
85 | } |
||||
86 | |||||
87 | /** |
||||
88 | * @param string[] $failedRecipients |
||||
89 | * @param bool $noSpoolPath |
||||
90 | * @param bool $noTransport |
||||
91 | * @param null $msgCount |
||||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||||
92 | * |
||||
93 | * @internal param string $message |
||||
94 | * |
||||
95 | * @return ContainerInterface |
||||
96 | */ |
||||
97 | private function getMockSetup($failedRecipients, $noSpoolPath = false, $noTransport = false, $msgCount = null) |
||||
98 | { |
||||
99 | if (null == $msgCount) { |
||||
0 ignored issues
–
show
|
|||||
100 | $msgCount = $this->once(); |
||||
101 | } |
||||
102 | |||||
103 | $containerMock = $this->getMockBuilder("Symfony\Component\DependencyInjection\ContainerInterface")->disableOriginalConstructor()->getMock(); |
||||
104 | |||||
105 | if ($noTransport) { |
||||
106 | $containerMock->expects($this->once())->method('get')->will($this->throwException(new ServiceNotFoundException('swiftmailer.transport.real'))); |
||||
107 | |||||
108 | return $containerMock; |
||||
0 ignored issues
–
show
|
|||||
109 | } |
||||
110 | |||||
111 | $transportMock = $this->getMockBuilder("\Swift_SmtpTransport")->getMock(); |
||||
112 | |||||
113 | if ($noSpoolPath) { |
||||
114 | $containerMock->expects($this->once())->method('get')->will($this->returnValue($transportMock)); |
||||
115 | $containerMock->expects($this->once())->method('getParameter')->will($this->throwException(new InvalidArgumentException())); |
||||
116 | |||||
117 | return $containerMock; |
||||
0 ignored issues
–
show
|
|||||
118 | } |
||||
119 | |||||
120 | $loggerMock = $this->getMockBuilder("Psr\Log\LoggerInterface")->disableOriginalConstructor()->getMock(); |
||||
121 | if (sizeof($failedRecipients) > 0) { |
||||
122 | $loggerMock->expects($this->once())->method('warning')->with('<error>Failed to send an email to : '.implode(', ', $failedRecipients).'</error>'); |
||||
123 | $getServiceCallCount = $this->exactly(2); |
||||
124 | } else { |
||||
125 | $loggerMock->expects($this->never())->method('warning'); |
||||
126 | $getServiceCallCount = $this->once(); |
||||
127 | } |
||||
128 | |||||
129 | $transportMock->expects($this->once())->method('isStarted')->will($this->returnValue(false)); |
||||
130 | $transportMock->expects($this->once())->method('start'); |
||||
131 | $this->failedRecipients = $failedRecipients; |
||||
132 | $transportMock->expects($msgCount)->method('send')->will($this->returnCallback(array($this, 'send_failures_callback'))); |
||||
133 | |||||
134 | $containerMock->expects($getServiceCallCount)->method('get')->will($this->returnValueMap(array( |
||||
135 | array('swiftmailer.transport.real', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $transportMock), |
||||
136 | array('logger', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $loggerMock), |
||||
137 | ))); |
||||
138 | $containerMock->expects($this->exactly(2))->method('getParameter')->will($this->returnValueMap(array( |
||||
139 | array('swiftmailer.mailers', array('default_mailer' => 'a dummy value for a mailer')), |
||||
140 | array('swiftmailer.spool.default_mailer.file.path', __DIR__.'/mock.spool.path'), |
||||
141 | ))); |
||||
142 | |||||
143 | return $containerMock; |
||||
0 ignored issues
–
show
|
|||||
144 | } |
||||
145 | |||||
146 | private $failedRecipients = array(); |
||||
147 | |||||
148 | public function send_failures_callback($message, &$failedRecipients = null) |
||||
149 | { |
||||
150 | if (sizeof($this->failedRecipients) > 0) { |
||||
151 | $failedRecipients[] = array_pop($this->failedRecipients); |
||||
152 | } |
||||
153 | } |
||||
154 | |||||
155 | private function createFakeFailedMessageFiles($count = 1) |
||||
156 | { |
||||
157 | $targetDir = __DIR__.'/mock.spool.path/'; |
||||
158 | |||||
159 | $i = 0; |
||||
160 | while ($i < $count) { |
||||
161 | $random = md5(date('now')).$count.rand(0, 10000000); |
||||
162 | $filename = $targetDir."$random.sending"; |
||||
163 | $msg = new \Swift_Message(); |
||||
164 | $msg->setTo('[email protected]'); |
||||
165 | $msg->setBody("random file $random bla bla."); |
||||
166 | $msg->setSubject('subject blabbla'); |
||||
167 | $msg->setSender('[email protected]'); |
||||
168 | $ser = serialize($msg); |
||||
169 | $filehandle = fopen($filename, 'w'); |
||||
170 | fwrite($filehandle, $ser); |
||||
0 ignored issues
–
show
It seems like
$filehandle can also be of type false ; however, parameter $handle of fwrite() does only seem to accept resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
171 | fclose($filehandle); |
||||
0 ignored issues
–
show
It seems like
$filehandle can also be of type false ; however, parameter $handle of fclose() does only seem to accept resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
172 | ++$i; |
||||
173 | } |
||||
174 | |||||
175 | // make sure the right number of files has been created. |
||||
176 | $fileCount = 0; |
||||
177 | $targetDirHandle = opendir($targetDir); |
||||
178 | while (false !== ($file = readdir($targetDirHandle))) { |
||||
0 ignored issues
–
show
It seems like
$targetDirHandle can also be of type false ; however, parameter $dir_handle of readdir() does only seem to accept resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
179 | ++$fileCount; |
||||
180 | } |
||||
181 | $this->assertSame($count + 3, $fileCount, "Exactly $count + 2 files (*.sending, '.', '..' and '.keepMe') expected in this directory( $targetDir )."); |
||||
182 | } |
||||
183 | |||||
184 | /** |
||||
185 | * @return ClearAndLogFailedMailsCommand |
||||
186 | */ |
||||
187 | private function getCommand() |
||||
188 | { |
||||
189 | $application = new Application(); |
||||
190 | $application->add(new ClearAndLogFailedMailsCommand()); |
||||
191 | |||||
192 | return $application->find('emails:clear-and-log-failures'); |
||||
193 | } |
||||
194 | |||||
195 | /** |
||||
196 | * @param ClearAndLogFailedMailsCommand $command |
||||
197 | * @param array $input |
||||
198 | * |
||||
199 | * @return string |
||||
200 | */ |
||||
201 | private function executeCommandAndGetDisplay($command, $input) |
||||
202 | { |
||||
203 | $tester = new CommandTester($command); |
||||
204 | $tester->execute($input); |
||||
205 | $display = $tester->getDisplay(); |
||||
206 | |||||
207 | return $display; |
||||
208 | } |
||||
209 | |||||
210 | public function tearDown() |
||||
211 | { |
||||
212 | parent::tearDown(); |
||||
213 | $finder = Finder::create()->in(__DIR__.'/mock.spool.path/')->name('*'); |
||||
214 | foreach ($finder as $next) { |
||||
215 | unlink($next); |
||||
216 | } |
||||
217 | } |
||||
218 | } |
||||
219 |