Passed
Push — master ( 9213a8...e174b6 )
by Kevin
02:14
created

ScheduleTest::runContext()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

190
        $schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ 
191
                                       filterSchedule(self::runContext($schedule));
Loading history...
191
    }
192
193
    /**
194
     * @test
195
     */
196
    public function callback_returning_false_when_filter_skips_schedule()
197
    {
198
        $schedule = new Schedule();
199
200
        $schedule->when('callback value', function () { return false; });
201
202
        $this->expectException(SkipSchedule::class);
203
        $this->expectExceptionMessage('callback value');
204
205
        $schedule->getExtensions()[0]->filterSchedule(self::runContext($schedule));
206
    }
207
208
    /**
209
     * @test
210
     */
211
    public function true_when_filter_allows_schedule_to_run()
212
    {
213
        $schedule = new Schedule();
214
215
        $schedule->when('boolean value', true);
216
217
        $schedule->getExtensions()[0]->filterSchedule(self::runContext($schedule));
218
219
        $this->assertTrue(true);
220
    }
221
222
    /**
223
     * @test
224
     */
225
    public function callback_returning_true_when_filter_allows_schedule_to_run()
226
    {
227
        $schedule = new Schedule();
228
229
        $schedule->when('callback value', function () { return true; });
230
231
        $schedule->getExtensions()[0]->filterSchedule(self::runContext($schedule));
232
233
        $this->assertTrue(true);
234
    }
235
236
    /**
237
     * @test
238
     */
239
    public function true_skip_filter_skips_schedule()
240
    {
241
        $schedule = new Schedule();
242
243
        $schedule->skip('boolean value', true);
244
245
        $this->expectException(SkipSchedule::class);
246
        $this->expectExceptionMessage('boolean value');
247
248
        $schedule->getExtensions()[0]->filterSchedule(self::runContext($schedule));
249
    }
250
251
    /**
252
     * @test
253
     */
254
    public function callback_returning_true_skip_filter_skips_schedule()
255
    {
256
        $schedule = new Schedule();
257
258
        $schedule->skip('callback value', function () { return true; });
259
260
        $this->expectException(SkipSchedule::class);
261
        $this->expectExceptionMessage('callback value');
262
263
        $schedule->getExtensions()[0]->filterSchedule(self::runContext($schedule));
264
    }
265
266
    /**
267
     * @test
268
     */
269
    public function false_skip_filter_allows_schedule_to_run()
270
    {
271
        $schedule = new Schedule();
272
273
        $schedule->skip('boolean value', false);
274
275
        $schedule->getExtensions()[0]->filterSchedule(self::runContext($schedule));
276
277
        $this->assertTrue(true);
278
    }
279
280
    /**
281
     * @test
282
     */
283
    public function callback_returning_false_skip_filter_allows_schedule_to_run()
284
    {
285
        $schedule = new Schedule();
286
287
        $schedule->skip('callback value', function () { return false; });
288
289
        $schedule->getExtensions()[0]->filterSchedule(self::runContext($schedule));
290
291
        $this->assertTrue(true);
292
    }
293
294
    /**
295
     * @test
296
     */
297
    public function can_add_callback_extensions()
298
    {
299
        $schedule = new Schedule();
300
        $calls = [];
301
302
        $schedule->filter(function () use (&$calls) { $calls[] = 'filter'; });
303
        $schedule->before(function () use (&$calls) { $calls[] = 'before'; });
304
        $schedule->after(function () use (&$calls) { $calls[] = 'after'; });
305
        $schedule->then(function () use (&$calls) { $calls[] = 'then'; });
306
        $schedule->onSuccess(function () use (&$calls) { $calls[] = 'onSuccess'; });
307
        $schedule->onFailure(function () use (&$calls) { $calls[] = 'onFailure'; });
308
309
        $schedule->getExtensions()[0]->filterSchedule(self::runContext($schedule));
310
        $schedule->getExtensions()[1]->beforeSchedule(self::runContext($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

310
        $schedule->getExtensions()[1]->/** @scrutinizer ignore-call */ 
311
                                       beforeSchedule(self::runContext($schedule));
Loading history...
311
        $schedule->getExtensions()[2]->afterSchedule(self::runContext($schedule));
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

311
        $schedule->getExtensions()[2]->/** @scrutinizer ignore-call */ 
312
                                       afterSchedule(self::runContext($schedule));
Loading history...
312
        $schedule->getExtensions()[3]->afterSchedule(self::runContext($schedule));
313
        $schedule->getExtensions()[4]->onScheduleSuccess(self::runContext($schedule));
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

313
        $schedule->getExtensions()[4]->/** @scrutinizer ignore-call */ 
314
                                       onScheduleSuccess(self::runContext($schedule));
Loading history...
314
        $schedule->getExtensions()[5]->onScheduleFailure(self::runContext($schedule));
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

314
        $schedule->getExtensions()[5]->/** @scrutinizer ignore-call */ 
315
                                       onScheduleFailure(self::runContext($schedule));
Loading history...
315
316
        $this->assertSame([
317
            'filter',
318
            'before',
319
            'after',
320
            'then',
321
            'onSuccess',
322
            'onFailure',
323
        ], $calls);
324
    }
325
326
    /**
327
     * @test
328
     */
329
    public function can_add_single_server_extension()
330
    {
331
        $schedule = new Schedule();
332
        $schedule->addCommand('my:command');
333
        $schedule->onSingleServer();
334
335
        $this->assertInstanceOf(SingleServerExtension::class, $schedule->getExtensions()[0]);
336
    }
337
338
    /**
339
     * @test
340
     */
341
    public function can_add_ping_extensions()
342
    {
343
        $schedule = new Schedule();
344
345
        $schedule->pingBefore('http://before.com');
346
        $schedule->pingAfter('http://after.com', 'POST');
347
        $schedule->thenPing('http://then.com');
348
        $schedule->pingOnSuccess('http://success.com');
349
        $schedule->pingOnFailure('http://failure.com');
350
351
        $client = $this->createMock(HttpClientInterface::class);
352
        $client->expects($this->exactly(5))->method('request')->withConsecutive(
353
            [$this->equalTo('GET'), $this->equalTo('http://before.com'), $this->isType('array')],
354
            [$this->equalTo('POST'), $this->equalTo('http://after.com'), $this->isType('array')],
355
            [$this->equalTo('GET'), $this->equalTo('http://then.com'), $this->isType('array')],
356
            [$this->equalTo('GET'), $this->equalTo('http://success.com'), $this->isType('array')],
357
            [$this->equalTo('GET'), $this->equalTo('http://failure.com'), $this->isType('array')]
358
        );
359
360
        $schedule->getExtensions()[0]->setHttpClient($client)->beforeSchedule(self::runContext($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

360
        $schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ 
361
                                       setHttpClient($client)->beforeSchedule(self::runContext($schedule));
Loading history...
361
        $schedule->getExtensions()[1]->setHttpClient($client)->afterSchedule(self::runContext($schedule));
362
        $schedule->getExtensions()[2]->setHttpClient($client)->afterSchedule(self::runContext($schedule));
363
        $schedule->getExtensions()[3]->setHttpClient($client)->onScheduleSuccess(self::runContext($schedule));
364
        $schedule->getExtensions()[4]->setHttpClient($client)->onScheduleFailure(self::runContext($schedule));
365
    }
366
367
    /**
368
     * @test
369
     */
370
    public function can_add_email_on_failure_extension()
371
    {
372
        $schedule = new Schedule();
373
        $schedule->emailOnFailure('[email protected]', 'my subject', function (Email $email) {
374
            $email->cc('[email protected]');
375
        });
376
377
        $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

377
        $this->assertTrue($schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ isHook(Extension::SCHEDULE_FAILURE));
Loading history...
378
        $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

378
        $this->assertSame('[email protected]', $schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ getEmail()->getTo()[0]->toString());
Loading history...
379
        $this->assertSame('[email protected]', $schedule->getExtensions()[0]->getEmail()->getCc()[0]->toString());
380
        $this->assertSame('my subject', $schedule->getExtensions()[0]->getEmail()->getSubject());
381
    }
382
383
    /**
384
     * @test
385
     */
386
    public function can_add_environment_extension()
387
    {
388
        $schedule = new Schedule();
389
        $schedule->environments('prod', 'stage');
390
391
        $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

391
        $this->assertSame(['prod', 'stage'], $schedule->getExtensions()[0]->/** @scrutinizer ignore-call */ getRunEnvironments());
Loading history...
392
    }
393
394
    /**
395
     * @test
396
     */
397
    public function can_set_timezone()
398
    {
399
        $schedule = new Schedule();
400
        $schedule->add((new MockTask())->description('task1'));
401
        $schedule->add((new MockTask())->description('task2')->timezone('America/Toronto'));
402
403
        $this->assertNull($schedule->getTimezone());
404
        $this->assertNull($schedule->all()[0]->getTimezone());
405
        $this->assertNull($schedule->due()[0]->getTimezone());
406
        $this->assertSame('America/Toronto', $schedule->all()[1]->getTimezone()->getName());
407
        $this->assertSame('America/Toronto', $schedule->due()[1]->getTimezone()->getName());
408
409
        $schedule->timezone('UTC');
410
411
        $this->assertSame('UTC', $schedule->getTimezone()->getName());
412
        $this->assertSame('UTC', $schedule->all()[0]->getTimezone()->getName());
413
        $this->assertSame('UTC', $schedule->due()[0]->getTimezone()->getName());
414
        $this->assertSame('America/Toronto', $schedule->all()[1]->getTimezone()->getName());
415
        $this->assertSame('America/Toronto', $schedule->due()[1]->getTimezone()->getName());
416
417
        $schedule->timezone(new \DateTimeZone('America/Los_Angeles'));
418
419
        $this->assertSame('America/Los_Angeles', $schedule->getTimezone()->getName());
420
        $this->assertSame('UTC', $schedule->all()[0]->getTimezone()->getName());
421
        $this->assertSame('UTC', $schedule->due()[0]->getTimezone()->getName());
422
        $this->assertSame('America/Toronto', $schedule->all()[1]->getTimezone()->getName());
423
        $this->assertSame('America/Toronto', $schedule->due()[1]->getTimezone()->getName());
424
    }
425
426
    private static function runContext(Schedule $schedule = null): ScheduleRunContext
427
    {
428
        return new ScheduleRunContext($schedule ?: new Schedule());
429
    }
430
}
431