Issues (91)

tests/Schedule/Extension/EmailExtensionTest.php (6 issues)

Labels
Severity
1
<?php
2
3
namespace Zenstruck\ScheduleBundle\Tests\Schedule\Extension;
4
5
use PHPUnit\Framework\TestCase;
0 ignored issues
show
The type PHPUnit\Framework\TestCase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Symfony\Component\Mailer\Envelope;
7
use Symfony\Component\Mailer\MailerInterface;
8
use Symfony\Component\Mime\Email;
9
use Symfony\Component\Mime\RawMessage;
10
use Zenstruck\ScheduleBundle\Schedule;
11
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\EmailHandler;
12
use Zenstruck\ScheduleBundle\Schedule\ScheduleBuilder;
13
use Zenstruck\ScheduleBundle\Tests\Fixture\MockScheduleBuilder;
14
use Zenstruck\ScheduleBundle\Tests\Fixture\MockTask;
15
16
/**
17
 * @author Kevin Bond <[email protected]>
18
 */
19
final class EmailExtensionTest extends TestCase
20
{
21
    /**
22
     * @test
23
     */
24
    public function sends_schedule_failure_email()
25
    {
26
        $mailer = $this->createMailer();
27
28
        (new MockScheduleBuilder())
29
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]'))
30
            ->addBuilder(new class() implements ScheduleBuilder {
31
                public function buildSchedule(Schedule $schedule): void
32
                {
33
                    $schedule->emailOnFailure();
34
                }
35
            })
36
            ->addTask($task1 = MockTask::exception(new \Exception('task 1 exception message'), 'my task 1'))
37
            ->addTask(MockTask::success('my task 2'))
38
            ->addTask($task2 = MockTask::exception(new \Exception('task 3 exception message'), 'my task 3'))
39
            ->run()
40
        ;
41
42
        $this->assertSame('[email protected]', $mailer->lastMessage->getFrom()[0]->getAddress());
0 ignored issues
show
The method getFrom() does not exist on Symfony\Component\Mime\RawMessage. It seems like you code against a sub-type of Symfony\Component\Mime\RawMessage such as Symfony\Component\Mime\Email. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

42
        $this->assertSame('[email protected]', $mailer->lastMessage->/** @scrutinizer ignore-call */ getFrom()[0]->getAddress());
Loading history...
43
        $this->assertSame('[email protected]', $mailer->lastMessage->getTo()[0]->getAddress());
0 ignored issues
show
The method getTo() does not exist on Symfony\Component\Mime\RawMessage. It seems like you code against a sub-type of Symfony\Component\Mime\RawMessage such as Symfony\Component\Mime\Email. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

43
        $this->assertSame('[email protected]', $mailer->lastMessage->/** @scrutinizer ignore-call */ getTo()[0]->getAddress());
Loading history...
44
        $this->assertSame('[Schedule Failure] 2 tasks failed', $mailer->lastMessage->getSubject());
0 ignored issues
show
The method getSubject() does not exist on Symfony\Component\Mime\RawMessage. It seems like you code against a sub-type of Symfony\Component\Mime\RawMessage such as Symfony\Component\Mime\Email. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
        $this->assertSame('[Schedule Failure] 2 tasks failed', $mailer->lastMessage->/** @scrutinizer ignore-call */ getSubject());
Loading history...
45
        $this->assertStringContainsString('2 tasks failed', $mailer->lastMessage->getTextBody());
0 ignored issues
show
The method getTextBody() does not exist on Symfony\Component\Mime\RawMessage. It seems like you code against a sub-type of Symfony\Component\Mime\RawMessage such as Symfony\Component\Mime\Email. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
        $this->assertStringContainsString('2 tasks failed', $mailer->lastMessage->/** @scrutinizer ignore-call */ getTextBody());
Loading history...
46
        $this->assertStringContainsString('# (Failure 1/2) MockTask: my task 1', $mailer->lastMessage->getTextBody());
47
        $this->assertStringContainsString('## Exception', $mailer->lastMessage->getTextBody());
48
        $this->assertStringContainsString('Exception: task 1 exception message', $mailer->lastMessage->getTextBody());
49
        $this->assertStringContainsString('# (Failure 2/2) MockTask: my task 3', $mailer->lastMessage->getTextBody());
50
        $this->assertStringContainsString('## Exception', $mailer->lastMessage->getTextBody());
51
        $this->assertStringContainsString('Exception: task 3 exception message', $mailer->lastMessage->getTextBody());
52
        $this->assertStringContainsString('Task ID: '.$task1->getId(), $mailer->lastMessage->getTextBody());
53
        $this->assertStringContainsString('Task ID: '.$task2->getId(), $mailer->lastMessage->getTextBody());
54
    }
55
56
    /**
57
     * @test
58
     */
59
    public function sends_schedule_failure_email_with_overrides()
60
    {
61
        $mailer = $this->createMailer();
62
63
        (new MockScheduleBuilder())
64
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]'))
65
            ->addBuilder(new class() implements ScheduleBuilder {
66
                public function buildSchedule(Schedule $schedule): void
67
                {
68
                    $schedule->emailOnFailure('[email protected]', 'my subject', function(Email $email) {
69
                        $email->cc('[email protected]');
70
                    });
71
                }
72
            })
73
            ->addTask(MockTask::exception(new \Exception('task 1 exception message'), 'my task 1'))
74
            ->addTask(MockTask::success('my task 2'))
75
            ->addTask(MockTask::exception(new \Exception('task 3 exception message'), 'my task 3'))
76
            ->run()
77
        ;
78
79
        $this->assertSame('[email protected]', $mailer->lastMessage->getTo()[0]->getAddress());
80
        $this->assertSame('my subject', $mailer->lastMessage->getSubject());
81
        $this->assertSame('[email protected]', $mailer->lastMessage->getCc()[0]->getAddress());
0 ignored issues
show
The method getCc() does not exist on Symfony\Component\Mime\RawMessage. It seems like you code against a sub-type of Symfony\Component\Mime\RawMessage such as Symfony\Component\Mime\Email. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

81
        $this->assertSame('[email protected]', $mailer->lastMessage->/** @scrutinizer ignore-call */ getCc()[0]->getAddress());
Loading history...
82
    }
83
84
    /**
85
     * @test
86
     */
87
    public function sends_schedule_failure_email_with_configured_subject_prefix()
88
    {
89
        $mailer = $this->createMailer();
90
91
        (new MockScheduleBuilder())
92
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]', '[Acme Inc]'))
93
            ->addBuilder(new class() implements ScheduleBuilder {
94
                public function buildSchedule(Schedule $schedule): void
95
                {
96
                    $schedule->emailOnFailure();
97
                }
98
            })
99
            ->addTask(MockTask::exception(new \Exception('task 1 exception message'), 'my task 1'))
100
            ->addTask(MockTask::success('my task 2'))
101
            ->addTask(MockTask::exception(new \Exception('task 3 exception message'), 'my task 3'))
102
            ->run()
103
        ;
104
105
        $this->assertSame('[Acme Inc][Schedule Failure] 2 tasks failed', $mailer->lastMessage->getSubject());
106
    }
107
108
    /**
109
     * @test
110
     */
111
    public function sends_task_failure_email()
112
    {
113
        $mailer = $this->createMailer();
114
115
        (new MockScheduleBuilder())
116
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]'))
117
            ->addTask($task = MockTask::failure('Exit 127: Command not found', 'my task', 'sh: 1: sdsdsd: not found')
118
                ->emailOnFailure()
119
            )
120
            ->run()
121
        ;
122
123
        $this->assertSame('[email protected]', $mailer->lastMessage->getFrom()[0]->getAddress());
124
        $this->assertSame('[email protected]', $mailer->lastMessage->getTo()[0]->getAddress());
125
        $this->assertSame('[Scheduled Task Failed] MockTask: my task', $mailer->lastMessage->getSubject());
126
        $this->assertStringContainsString('Exit 127: Command not found', $mailer->lastMessage->getTextBody());
127
        $this->assertStringContainsString('## Task Output:', $mailer->lastMessage->getTextBody());
128
        $this->assertStringContainsString('sh: 1: sdsdsd: not found', $mailer->lastMessage->getTextBody());
129
        $this->assertStringContainsString('Task ID: '.$task->getId(), $mailer->lastMessage->getTextBody());
130
    }
131
132
    /**
133
     * @test
134
     */
135
    public function sends_task_failure_email_with_overrides()
136
    {
137
        $mailer = $this->createMailer();
138
139
        (new MockScheduleBuilder())
140
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]'))
141
            ->addTask(MockTask::failure('Exit 127: Command not found', 'my task', 'sh: 1: sdsdsd: not found')
142
                ->emailOnFailure('[email protected]', 'my subject', function(Email $email) {
143
                    $email->cc('[email protected]');
144
                })
145
            )
146
            ->run()
147
        ;
148
149
        $this->assertSame('[email protected]', $mailer->lastMessage->getTo()[0]->getAddress());
150
        $this->assertSame('my subject', $mailer->lastMessage->getSubject());
151
        $this->assertSame('[email protected]', $mailer->lastMessage->getCc()[0]->getAddress());
152
    }
153
154
    /**
155
     * @test
156
     */
157
    public function sends_task_failure_email_with_configured_subject_prefix()
158
    {
159
        $mailer = $this->createMailer();
160
161
        (new MockScheduleBuilder())
162
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]', '[Acme Inc]'))
163
            ->addTask(MockTask::failure('Exit 127: Command not found', 'my task', 'sh: 1: sdsdsd: not found')
164
                ->emailOnFailure()
165
            )
166
            ->run()
167
        ;
168
169
        $this->assertSame('[Acme Inc][Scheduled Task Failed] MockTask: my task', $mailer->lastMessage->getSubject());
170
    }
171
172
    /**
173
     * @test
174
     */
175
    public function sends_after_task_email()
176
    {
177
        $mailer = $this->createMailer();
178
179
        (new MockScheduleBuilder())
180
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]'))
181
            ->addTask($task = MockTask::success('my task', 'my task output')->emailAfter())
182
            ->run()
183
        ;
184
185
        $this->assertSame('[email protected]', $mailer->lastMessage->getFrom()[0]->getAddress());
186
        $this->assertSame('[email protected]', $mailer->lastMessage->getTo()[0]->getAddress());
187
        $this->assertSame('[Scheduled Task Succeeded] MockTask: my task', $mailer->lastMessage->getSubject());
188
        $this->assertStringContainsString('Successful', $mailer->lastMessage->getTextBody());
189
        $this->assertStringContainsString('## Task Output:', $mailer->lastMessage->getTextBody());
190
        $this->assertStringContainsString('my task output', $mailer->lastMessage->getTextBody());
191
        $this->assertStringContainsString('Task ID: '.$task->getId(), $mailer->lastMessage->getTextBody());
192
    }
193
194
    /**
195
     * @test
196
     */
197
    public function sends_after_task_email_with_overrides()
198
    {
199
        $mailer = $this->createMailer();
200
201
        (new MockScheduleBuilder())
202
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]'))
203
            ->addTask(MockTask::success('my task', 'my task output')
204
                ->emailAfter('[email protected]', 'my subject', function(Email $email) {
205
                    $email->cc('[email protected]');
206
                })
207
            )
208
            ->run()
209
        ;
210
211
        $this->assertSame('[email protected]', $mailer->lastMessage->getTo()[0]->getAddress());
212
        $this->assertSame('my subject', $mailer->lastMessage->getSubject());
213
        $this->assertSame('[email protected]', $mailer->lastMessage->getCc()[0]->getAddress());
214
    }
215
216
    /**
217
     * @test
218
     */
219
    public function sends_after_task_email_with_configured_subject_prefix()
220
    {
221
        $mailer = $this->createMailer();
222
223
        (new MockScheduleBuilder())
224
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]', '[Acme Inc]'))
225
            ->addTask(MockTask::success('my task', 'my task output')->emailAfter())
226
            ->run()
227
        ;
228
229
        $this->assertSame('[Acme Inc][Scheduled Task Succeeded] MockTask: my task', $mailer->lastMessage->getSubject());
230
    }
231
232
    /**
233
     * @test
234
     */
235
    public function provides_helpful_message_if_handler_not_configured()
236
    {
237
        $this->expectException(\LogicException::class);
238
        $this->expectExceptionMessage('To use the email extension you must configure a mailer (config path: "zenstruck_schedule.mailer").');
239
240
        (new MockScheduleBuilder())
241
            ->addBuilder(new class() implements ScheduleBuilder {
242
                public function buildSchedule(Schedule $schedule): void
243
                {
244
                    $schedule->emailOnFailure();
245
                }
246
            })
247
            ->run()
248
        ;
249
    }
250
251
    /**
252
     * @test
253
     */
254
    public function to_address_must_be_configured_or_passed_to_extension()
255
    {
256
        $context = (new MockScheduleBuilder())
257
            ->addHandler(new EmailHandler($this->createMailer()))
258
            ->addTask(MockTask::failure()->emailOnFailure())
259
            ->run()
260
        ;
261
262
        $this->assertInstanceOf(\LogicException::class, $context->getResults()[0]->getException());
263
        $this->assertSame('There is no "To" configured for the email. Either set it when adding the extension or in your configuration (config path: "zenstruck_schedule.mailer.default_to").', $context->getResults()[0]->getException()->getMessage());
264
    }
265
266
    /**
267
     * @test
268
     */
269
    public function email_shows_if_task_was_force_run()
270
    {
271
        $mailer = $this->createMailer();
272
273
        (new MockScheduleBuilder())
274
            ->addHandler(new EmailHandler($mailer, '[email protected]', '[email protected]'))
275
            ->addTask($task = MockTask::success('my task', 'my task output')->emailAfter())
276
            ->run($task->getId())
277
        ;
278
279
        $this->assertStringContainsString('This task was force run', $mailer->lastMessage->getTextBody());
280
    }
281
282
    private function createMailer(): MailerInterface
283
    {
284
        return new class() implements MailerInterface {
285
            /** @var RawMessage */
286
            public $lastMessage;
287
288
            public function send(RawMessage $message, ?Envelope $envelope = null): void
289
            {
290
                $this->lastMessage = $message;
291
            }
292
        };
293
    }
294
}
295