Passed
Push — master ( 8b3ece...7c044f )
by Kevin
01:49
created

due_tasks_are_ordered_by_when_they_are_defined()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 27
rs 9.584
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Zenstruck\ScheduleBundle\Tests;
4
5
use PHPUnit\Framework\TestCase;
0 ignored issues
show
Bug introduced by
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\Lock\LockFactory;
7
use Symfony\Component\Lock\Store\FlockStore;
8
use Symfony\Component\Mime\Email;
9
use Symfony\Component\Process\Process;
10
use Symfony\Contracts\HttpClient\HttpClientInterface;
11
use Zenstruck\ScheduleBundle\Event\AfterScheduleEvent;
12
use Zenstruck\ScheduleBundle\Event\BeforeScheduleEvent;
13
use Zenstruck\ScheduleBundle\Schedule;
14
use Zenstruck\ScheduleBundle\Schedule\Exception\SkipSchedule;
15
use Zenstruck\ScheduleBundle\Schedule\Extension;
16
use Zenstruck\ScheduleBundle\Schedule\Task;
17
use Zenstruck\ScheduleBundle\Schedule\Task\CallbackTask;
18
use Zenstruck\ScheduleBundle\Schedule\Task\CommandTask;
19
use Zenstruck\ScheduleBundle\Tests\Fixture\MockTask;
20
21
/**
22
 * @author Kevin Bond <[email protected]>
23
 */
24
class ScheduleTest extends TestCase
25
{
26
    /**
27
     * @test
28
     */
29
    public function can_add_tasks()
30
    {
31
        $schedule = new Schedule();
32
33
        $schedule->add(new CallbackTask(function () {}))->description('task1');
34
        $schedule->addCallback(function () {})->description('task2');
35
        $schedule->addProcess('php -v')->description('task3');
36
        $schedule->addProcess(new Process(['php -v']))->description('task4');
37
        $schedule->addCommand('my:command')->description('task5');
38
39
        $this->assertCount(5, $schedule->all());
40
        $this->assertSame(['task1', 'task2', 'task3', 'task4', 'task5'], \array_map(
41
            function (Task $task) {
42
                return $task->getDescription();
43
            },
44
            $schedule->all()
45
        ));
46
47
        $this->assertCount(5, $schedule->all(), 'Caches the tasks');
48
49
        $schedule->addCommand('another:command');
50
51
        $this->assertCount(6, $schedule->all(), 'Resets the task cache on add');
52
    }
53
54
    /**
55
     * @test
56
     */
57
    public function can_add_compound_tasks()
58
    {
59
        $schedule = new Schedule();
60
61
        $schedule->addCommand('my:command')->description('task1')->tuesdays();
62
        $schedule->addCompound()
63
            ->addCommand('another:command', [], 'task2')
64
            ->addCallback(function () {}, 'task3')
65
            ->addProcess('php -v', 'task4')
66
            ->addProcess(new Process(['php -v']), 'task5')
67
            ->add((new CommandTask('yet:another:command'))
68
                ->description('task6')
69
                ->sundays()
70
                ->timezone('America/Los_Angeles')
71
            )
72
            ->timezone('UTC')
73
            ->mondays()
74
            ->onSingleServer()
75
        ;
76
77
        $this->assertCount(6, $schedule->all());
78
        $this->assertSame('task1', $schedule->all()[0]->getDescription());
79
        $this->assertSame('* * * * 2', (string) $schedule->all()[0]->getExpression());
80
        $this->assertNull($schedule->all()[0]->getTimezone());
81
        $this->assertCount(0, $schedule->all()[0]->getExtensions());
82
        $this->assertSame('task2', $schedule->all()[1]->getDescription());
83
        $this->assertSame('* * * * 1', (string) $schedule->all()[1]->getExpression());
84
        $this->assertSame('UTC', $schedule->all()[1]->getTimezone()->getName());
85
        $this->assertCount(1, $schedule->all()[1]->getExtensions());
86
        $this->assertSame('task3', $schedule->all()[2]->getDescription());
87
        $this->assertSame('* * * * 1', (string) $schedule->all()[2]->getExpression());
88
        $this->assertSame('UTC', $schedule->all()[2]->getTimezone()->getName());
89
        $this->assertCount(1, $schedule->all()[2]->getExtensions());
90
        $this->assertSame('task4', $schedule->all()[3]->getDescription());
91
        $this->assertSame('* * * * 1', (string) $schedule->all()[3]->getExpression());
92
        $this->assertSame('UTC', $schedule->all()[3]->getTimezone()->getName());
93
        $this->assertCount(1, $schedule->all()[3]->getExtensions());
94
        $this->assertSame('task5', $schedule->all()[4]->getDescription());
95
        $this->assertSame('* * * * 1', (string) $schedule->all()[4]->getExpression());
96
        $this->assertSame('UTC', $schedule->all()[4]->getTimezone()->getName());
97
        $this->assertCount(1, $schedule->all()[4]->getExtensions());
98
        $this->assertSame('task6', $schedule->all()[5]->getDescription());
99
        $this->assertSame('* * * * 1', (string) $schedule->all()[5]->getExpression());
100
        $this->assertSame('UTC', $schedule->all()[5]->getTimezone()->getName());
101
        $this->assertCount(1, $schedule->all()[5]->getExtensions());
102
    }
103
104
    /**
105
     * @test
106
     */
107
    public function can_get_due_tasks()
108
    {
109
        $schedule = new Schedule();
110
111
        $schedule->addCallback(function () {})->description('task1');
112
        $notDueTask = $schedule->addProcess('php -v')->description('task2')->sundays();
113
114
        if ('Sun' === \date('D')) {
115
            $notDueTask->mondays();
116
        }
117
118
        $this->assertCount(2, $schedule->all());
119
        $this->assertCount(1, $schedule->due());
120
        $this->assertCount(1, $schedule->due(), 'Due tasks are cached');
121
        $this->assertSame('task1', $schedule->due()[0]->getDescription());
122
123
        $schedule->addCommand('my:command')->description('task3');
124
125
        $this->assertCount(2, $schedule->due(), 'Resets the due task cache');
126
    }
127
128
    /**
129
     * @test
130
     */
131
    public function due_tasks_are_ordered_by_when_they_are_defined()
132
    {
133
        $schedule = new Schedule();
134
135
        $schedule->addCommand('my:command')->description('task1');
136
        $schedule->addCompound()
137
            ->addCommand('another:command', [], 'task2')
138
            ->addCallback(function () {}, 'task3')
139
            ->addProcess('php -v', 'task4')
140
            ->addProcess(new Process(['php -v']), 'task5')
141
            ->timezone('UTC')
142
            ->mondays()
143
            ->onSingleServer()
144
        ;
145
        $schedule->addCommand('my:command')->description('task6');
146
147
        $this->assertSame(
148
            [
149
                'task1',
150
                'task2',
151
                'task3',
152
                'task4',
153
                'task5',
154
                'task6',
155
            ], \array_map(function (Task $task) {
156
                return $task->getDescription();
157
            }, $schedule->due())
158
        );
159
    }
160
161
    /**
162
     * @test
163
     */
164
    public function has_unique_id_based_on_tasks()
165
    {
166
        $schedule1 = new Schedule();
167
        $schedule1->addCommand('my:command');
168
        $schedule2 = new Schedule();
169
        $schedule2->addCommand('my:command');
170
        $schedule3 = new Schedule();
171
        $schedule3->addCommand('another:command');
172
        $schedule4 = new Schedule();
173
        $schedule4->addCommand('my:command');
174
        $schedule4->addCommand('another:command');
175
176
        $this->assertSame((new Schedule())->getId(), (new Schedule())->getId());
177
        $this->assertSame($schedule1->getId(), $schedule2->getId());
178
        $this->assertNotSame($schedule2->getId(), $schedule3->getId());
179
        $this->assertNotSame($schedule2->getId(), $schedule4->getId());
180
    }
181
182
    /**
183
     * @test
184
     */
185
    public function false_when_filter_skips_schedule()
186
    {
187
        $schedule = new Schedule();
188
189
        $schedule->when('boolean value', false);
190
191
        $this->expectException(SkipSchedule::class);
192
        $this->expectExceptionMessage('boolean value');
193
194
        $schedule->getExtensions()[0]->filterSchedule(new BeforeScheduleEvent($schedule));
0 ignored issues
show
Bug introduced by
The method filterSchedule() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

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

194
        $schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ 
195
                                       filterSchedule(new BeforeScheduleEvent($schedule));
Loading history...
195
    }
196
197
    /**
198
     * @test
199
     */
200
    public function callback_returning_false_when_filter_skips_schedule()
201
    {
202
        $schedule = new Schedule();
203
204
        $schedule->when('callback value', function () { return false; });
205
206
        $this->expectException(SkipSchedule::class);
207
        $this->expectExceptionMessage('callback value');
208
209
        $schedule->getExtensions()[0]->filterSchedule(new BeforeScheduleEvent($schedule));
210
    }
211
212
    /**
213
     * @test
214
     */
215
    public function true_when_filter_allows_schedule_to_run()
216
    {
217
        $schedule = new Schedule();
218
219
        $schedule->when('boolean value', true);
220
221
        $schedule->getExtensions()[0]->filterSchedule(new BeforeScheduleEvent($schedule));
222
223
        $this->assertTrue(true);
224
    }
225
226
    /**
227
     * @test
228
     */
229
    public function callback_returning_true_when_filter_allows_schedule_to_run()
230
    {
231
        $schedule = new Schedule();
232
233
        $schedule->when('callback value', function () { return true; });
234
235
        $schedule->getExtensions()[0]->filterSchedule(new BeforeScheduleEvent($schedule));
236
237
        $this->assertTrue(true);
238
    }
239
240
    /**
241
     * @test
242
     */
243
    public function true_skip_filter_skips_schedule()
244
    {
245
        $schedule = new Schedule();
246
247
        $schedule->skip('boolean value', true);
248
249
        $this->expectException(SkipSchedule::class);
250
        $this->expectExceptionMessage('boolean value');
251
252
        $schedule->getExtensions()[0]->filterSchedule(new BeforeScheduleEvent($schedule));
253
    }
254
255
    /**
256
     * @test
257
     */
258
    public function callback_returning_true_skip_filter_skips_schedule()
259
    {
260
        $schedule = new Schedule();
261
262
        $schedule->skip('callback value', function () { return true; });
263
264
        $this->expectException(SkipSchedule::class);
265
        $this->expectExceptionMessage('callback value');
266
267
        $schedule->getExtensions()[0]->filterSchedule(new BeforeScheduleEvent($schedule));
268
    }
269
270
    /**
271
     * @test
272
     */
273
    public function false_skip_filter_allows_schedule_to_run()
274
    {
275
        $schedule = new Schedule();
276
277
        $schedule->skip('boolean value', false);
278
279
        $schedule->getExtensions()[0]->filterSchedule(new BeforeScheduleEvent($schedule));
280
281
        $this->assertTrue(true);
282
    }
283
284
    /**
285
     * @test
286
     */
287
    public function callback_returning_false_skip_filter_allows_schedule_to_run()
288
    {
289
        $schedule = new Schedule();
290
291
        $schedule->skip('callback value', function () { return false; });
292
293
        $schedule->getExtensions()[0]->filterSchedule(new BeforeScheduleEvent($schedule));
294
295
        $this->assertTrue(true);
296
    }
297
298
    /**
299
     * @test
300
     */
301
    public function can_add_callback_extensions()
302
    {
303
        $schedule = new Schedule();
304
        $calls = [];
305
306
        $schedule->filter(function () use (&$calls) { $calls[] = 'filter'; });
307
        $schedule->before(function () use (&$calls) { $calls[] = 'before'; });
308
        $schedule->after(function () use (&$calls) { $calls[] = 'after'; });
309
        $schedule->then(function () use (&$calls) { $calls[] = 'then'; });
310
        $schedule->onSuccess(function () use (&$calls) { $calls[] = 'onSuccess'; });
311
        $schedule->onFailure(function () use (&$calls) { $calls[] = 'onFailure'; });
312
313
        $schedule->getExtensions()[0]->filterSchedule($event = new BeforeScheduleEvent($schedule));
314
        $schedule->getExtensions()[1]->beforeSchedule(new BeforeScheduleEvent($schedule));
0 ignored issues
show
Bug introduced by
The method beforeSchedule() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

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

314
        $schedule->getExtensions()[1]->/** @scrutinizer ignore-call */ 
315
                                       beforeSchedule(new BeforeScheduleEvent($schedule));
Loading history...
315
        $schedule->getExtensions()[2]->afterSchedule(new AfterScheduleEvent($event, []));
0 ignored issues
show
Bug introduced by
The method afterSchedule() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

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

315
        $schedule->getExtensions()[2]->/** @scrutinizer ignore-call */ 
316
                                       afterSchedule(new AfterScheduleEvent($event, []));
Loading history...
316
        $schedule->getExtensions()[3]->afterSchedule(new AfterScheduleEvent($event, []));
317
        $schedule->getExtensions()[4]->onScheduleSuccess(new AfterScheduleEvent($event, []));
0 ignored issues
show
Bug introduced by
The method onScheduleSuccess() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

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

317
        $schedule->getExtensions()[4]->/** @scrutinizer ignore-call */ 
318
                                       onScheduleSuccess(new AfterScheduleEvent($event, []));
Loading history...
318
        $schedule->getExtensions()[5]->onScheduleFailure(new AfterScheduleEvent($event, []));
0 ignored issues
show
Bug introduced by
The method onScheduleFailure() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

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

318
        $schedule->getExtensions()[5]->/** @scrutinizer ignore-call */ 
319
                                       onScheduleFailure(new AfterScheduleEvent($event, []));
Loading history...
319
320
        $this->assertSame([
321
            'filter',
322
            'before',
323
            'after',
324
            'then',
325
            'onSuccess',
326
            'onFailure',
327
        ], $calls);
328
    }
329
330
    /**
331
     * @test
332
     */
333
    public function can_add_single_server_extension()
334
    {
335
        $schedule1 = new Schedule();
336
        $schedule1->addCommand('my:command');
337
        $schedule1->onSingleServer();
338
339
        $schedule2 = new Schedule();
340
        $schedule2->addCommand('my:command');
341
        $schedule2->onSingleServer();
342
343
        $lockFactory = new LockFactory(new FlockStore());
344
345
        $schedule1->getExtensions()[0]->aquireScheduleLock($lockFactory, $schedule1, \time());
0 ignored issues
show
Bug introduced by
The method aquireScheduleLock() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SingleServerExtension. ( Ignorable by Annotation )

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

345
        $schedule1->getExtensions()[0]->/** @scrutinizer ignore-call */ 
346
                                        aquireScheduleLock($lockFactory, $schedule1, \time());
Loading history...
346
347
        $this->expectException(SkipSchedule::class);
348
        $this->expectExceptionMessage('Schedule running on another server.');
349
350
        $schedule2->getExtensions()[0]->aquireScheduleLock($lockFactory, $schedule2, \time());
351
    }
352
353
    /**
354
     * @test
355
     */
356
    public function can_add_ping_extensions()
357
    {
358
        $schedule = new Schedule();
359
360
        $schedule->pingBefore('http://before.com');
361
        $schedule->pingAfter('http://after.com', 'POST');
362
        $schedule->thenPing('http://then.com');
363
        $schedule->pingOnSuccess('http://success.com');
364
        $schedule->pingOnFailure('http://failure.com');
365
366
        $client = $this->createMock(HttpClientInterface::class);
367
        $client->expects($this->exactly(5))->method('request')->withConsecutive(
368
            [$this->equalTo('GET'), $this->equalTo('http://before.com'), $this->isType('array')],
369
            [$this->equalTo('POST'), $this->equalTo('http://after.com'), $this->isType('array')],
370
            [$this->equalTo('GET'), $this->equalTo('http://then.com'), $this->isType('array')],
371
            [$this->equalTo('GET'), $this->equalTo('http://success.com'), $this->isType('array')],
372
            [$this->equalTo('GET'), $this->equalTo('http://failure.com'), $this->isType('array')]
373
        );
374
375
        $schedule->getExtensions()[0]->setHttpClient($client)->beforeSchedule($event = new BeforeScheduleEvent($schedule));
0 ignored issues
show
Bug introduced by
The method setHttpClient() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...Extension\PingExtension. ( Ignorable by Annotation )

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

375
        $schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ 
376
                                       setHttpClient($client)->beforeSchedule($event = new BeforeScheduleEvent($schedule));
Loading history...
376
        $schedule->getExtensions()[1]->setHttpClient($client)->afterSchedule(new AfterScheduleEvent($event, []));
377
        $schedule->getExtensions()[2]->setHttpClient($client)->afterSchedule(new AfterScheduleEvent($event, []));
378
        $schedule->getExtensions()[3]->setHttpClient($client)->onScheduleSuccess(new AfterScheduleEvent($event, []));
379
        $schedule->getExtensions()[4]->setHttpClient($client)->onScheduleFailure(new AfterScheduleEvent($event, []));
380
    }
381
382
    /**
383
     * @test
384
     */
385
    public function can_add_email_on_failure_extension()
386
    {
387
        $schedule = new Schedule();
388
        $schedule->emailOnFailure('[email protected]', 'my subject', function (Email $email) {
389
            $email->cc('[email protected]');
390
        });
391
392
        $this->assertTrue($schedule->getExtensions()[0]->isHook(Extension::SCHEDULE_FAILURE));
0 ignored issues
show
Bug introduced by
The method isHook() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...xtension\EmailExtension. ( Ignorable by Annotation )

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

392
        $this->assertTrue($schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ isHook(Extension::SCHEDULE_FAILURE));
Loading history...
393
        $this->assertSame('[email protected]', $schedule->getExtensions()[0]->getEmail()->getTo()[0]->toString());
0 ignored issues
show
Bug introduced by
The method getEmail() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...xtension\EmailExtension. ( Ignorable by Annotation )

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

393
        $this->assertSame('[email protected]', $schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ getEmail()->getTo()[0]->toString());
Loading history...
394
        $this->assertSame('[email protected]', $schedule->getExtensions()[0]->getEmail()->getCc()[0]->toString());
395
        $this->assertSame('my subject', $schedule->getExtensions()[0]->getEmail()->getSubject());
396
    }
397
398
    /**
399
     * @test
400
     */
401
    public function can_add_environment_extension()
402
    {
403
        $schedule = new Schedule();
404
        $schedule->environments('prod', 'stage');
405
406
        $this->assertSame(['prod', 'stage'], $schedule->getExtensions()[0]->getRunEnvironments());
0 ignored issues
show
Bug introduced by
The method getRunEnvironments() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...on\EnvironmentExtension. ( Ignorable by Annotation )

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

406
        $this->assertSame(['prod', 'stage'], $schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ getRunEnvironments());
Loading history...
407
    }
408
409
    /**
410
     * @test
411
     */
412
    public function can_set_timezone()
413
    {
414
        $schedule = new Schedule();
415
        $schedule->add((new MockTask())->description('task1'));
416
        $schedule->add((new MockTask())->description('task2')->timezone('America/Toronto'));
417
418
        $this->assertNull($schedule->getTimezone());
419
        $this->assertNull($schedule->all()[0]->getTimezone());
420
        $this->assertNull($schedule->due()[0]->getTimezone());
421
        $this->assertSame('America/Toronto', $schedule->all()[1]->getTimezone()->getName());
422
        $this->assertSame('America/Toronto', $schedule->due()[1]->getTimezone()->getName());
423
424
        $schedule->timezone('UTC');
425
426
        $this->assertSame('UTC', $schedule->getTimezone()->getName());
427
        $this->assertSame('UTC', $schedule->all()[0]->getTimezone()->getName());
428
        $this->assertSame('UTC', $schedule->due()[0]->getTimezone()->getName());
429
        $this->assertSame('America/Toronto', $schedule->all()[1]->getTimezone()->getName());
430
        $this->assertSame('America/Toronto', $schedule->due()[1]->getTimezone()->getName());
431
432
        $schedule->timezone(new \DateTimeZone('America/Los_Angeles'));
433
434
        $this->assertSame('America/Los_Angeles', $schedule->getTimezone()->getName());
435
        $this->assertSame('UTC', $schedule->all()[0]->getTimezone()->getName());
436
        $this->assertSame('UTC', $schedule->due()[0]->getTimezone()->getName());
437
        $this->assertSame('America/Toronto', $schedule->all()[1]->getTimezone()->getName());
438
        $this->assertSame('America/Toronto', $schedule->due()[1]->getTimezone()->getName());
439
    }
440
}
441