Passed
Push — master ( 0675d7...59fbae )
by Kevin
02:33
created

can_enable_messenger_with_default_bus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 6
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Zenstruck\ScheduleBundle\Tests\DependencyInjection;
4
5
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase;
6
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
7
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
8
use Zenstruck\ScheduleBundle\Command\ScheduleListCommand;
9
use Zenstruck\ScheduleBundle\Command\ScheduleRunCommand;
10
use Zenstruck\ScheduleBundle\DependencyInjection\ZenstruckScheduleExtension;
11
use Zenstruck\ScheduleBundle\EventListener\ScheduleBuilderSubscriber;
12
use Zenstruck\ScheduleBundle\EventListener\ScheduleExtensionSubscriber;
13
use Zenstruck\ScheduleBundle\EventListener\ScheduleLoggerSubscriber;
14
use Zenstruck\ScheduleBundle\EventListener\ScheduleTimezoneSubscriber;
15
use Zenstruck\ScheduleBundle\EventListener\SelfSchedulingCommandSubscriber;
16
use Zenstruck\ScheduleBundle\EventListener\TaskConfigurationSubscriber;
17
use Zenstruck\ScheduleBundle\Schedule\Extension\EmailExtension;
18
use Zenstruck\ScheduleBundle\Schedule\Extension\EnvironmentExtension;
19
use Zenstruck\ScheduleBundle\Schedule\Extension\ExtensionHandlerRegistry;
20
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\EmailHandler;
21
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\EnvironmentHandler;
22
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\PingHandler;
23
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\SingleServerHandler;
24
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\WithoutOverlappingHandler;
25
use Zenstruck\ScheduleBundle\Schedule\Extension\PingExtension;
26
use Zenstruck\ScheduleBundle\Schedule\Extension\SingleServerExtension;
27
use Zenstruck\ScheduleBundle\Schedule\Extension\WithoutOverlappingExtension;
28
use Zenstruck\ScheduleBundle\Schedule\ScheduleRunner;
29
use Zenstruck\ScheduleBundle\Schedule\Task\Runner\CallbackTaskRunner;
30
use Zenstruck\ScheduleBundle\Schedule\Task\Runner\CommandTaskRunner;
31
use Zenstruck\ScheduleBundle\Schedule\Task\Runner\MessageTaskRunner;
32
use Zenstruck\ScheduleBundle\Schedule\Task\Runner\PingTaskRunner;
33
use Zenstruck\ScheduleBundle\Schedule\Task\Runner\ProcessTaskRunner;
34
35
/**
36
 * @author Kevin Bond <[email protected]>
37
 */
38
final class ZenstruckScheduleExtensionTest extends AbstractExtensionTestCase
39
{
40
    /**
41
     * @test
42
     */
43
    public function empty_config_loads_default_services()
44
    {
45
        $this->load([]);
46
47
        $this->assertContainerBuilderHasService(ScheduleListCommand::class);
48
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleListCommand::class, 'console.command');
49
50
        $this->assertContainerBuilderHasService(ScheduleRunCommand::class);
51
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleRunCommand::class, 'console.command');
52
53
        $this->assertContainerBuilderHasService(ScheduleRunner::class);
54
55
        $this->assertContainerBuilderHasService(ScheduleBuilderSubscriber::class);
56
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleBuilderSubscriber::class, 'kernel.event_subscriber');
57
58
        $this->assertContainerBuilderHasService(ScheduleExtensionSubscriber::class);
59
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleExtensionSubscriber::class, 'kernel.event_subscriber');
60
61
        $this->assertContainerBuilderHasService(SelfSchedulingCommandSubscriber::class);
62
        $this->assertContainerBuilderHasServiceDefinitionWithTag(SelfSchedulingCommandSubscriber::class, 'kernel.event_subscriber');
63
64
        $this->assertContainerBuilderHasService(CommandTaskRunner::class);
65
        $this->assertContainerBuilderHasServiceDefinitionWithTag(CommandTaskRunner::class, 'schedule.task_runner');
66
67
        $this->assertContainerBuilderHasService(ProcessTaskRunner::class);
68
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ProcessTaskRunner::class, 'schedule.task_runner');
69
70
        $this->assertContainerBuilderHasService(CallbackTaskRunner::class);
71
        $this->assertContainerBuilderHasServiceDefinitionWithTag(CallbackTaskRunner::class, 'schedule.task_runner');
72
73
        $this->assertContainerBuilderHasService(ScheduleLoggerSubscriber::class);
74
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleLoggerSubscriber::class, 'kernel.event_subscriber');
75
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleLoggerSubscriber::class, 'monolog.logger', ['channel' => 'schedule']);
76
77
        $this->assertContainerBuilderHasService(ExtensionHandlerRegistry::class);
78
79
        $this->assertContainerBuilderHasService(EnvironmentHandler::class);
80
        $this->assertContainerBuilderHasServiceDefinitionWithTag(EnvironmentHandler::class, 'schedule.extension_handler');
81
82
        $this->assertContainerBuilderHasService(TaskConfigurationSubscriber::class);
83
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleBuilderSubscriber::class, 'kernel.event_subscriber');
84
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(TaskConfigurationSubscriber::class, 0, []);
85
86
        $this->assertContainerBuilderHasServiceDefinitionWithTag(PingHandler::class, 'schedule.extension_handler');
87
        $this->assertEmpty($this->container->findDefinition(PingHandler::class)->getArguments());
88
89
        $this->assertContainerBuilderHasServiceDefinitionWithTag(PingTaskRunner::class, 'schedule.task_runner');
90
        $this->assertEmpty($this->container->findDefinition(PingTaskRunner::class)->getArguments());
91
92
        $this->assertContainerBuilderHasServiceDefinitionWithTag(WithoutOverlappingHandler::class, 'schedule.extension_handler');
93
        $this->assertEmpty($this->container->findDefinition(WithoutOverlappingHandler::class)->getArguments());
94
    }
95
96
    /**
97
     * @test
98
     */
99
    public function can_configure_default_timezone()
100
    {
101
        $this->load(['timezone' => 'UTC']);
102
103
        $this->assertContainerBuilderHasService(ScheduleTimezoneSubscriber::class);
104
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(ScheduleTimezoneSubscriber::class, 0, 'UTC');
105
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleTimezoneSubscriber::class, 'kernel.event_subscriber');
106
    }
107
108
    /**
109
     * @test
110
     */
111
    public function schedule_timezone_must_be_valid()
112
    {
113
        $this->expectException(InvalidConfigurationException::class);
114
        $this->expectExceptionMessage('Invalid configuration for path "zenstruck_schedule.timezone": Timezone "invalid" is not available');
115
116
        $this->load(['timezone' => 'invalid']);
117
    }
118
119
    /**
120
     * @test
121
     */
122
    public function can_configure_single_server_lock_factory()
123
    {
124
        $this->load(['single_server_lock_factory' => 'my_factory']);
125
126
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(SingleServerHandler::class, 0, 'my_factory');
127
        $this->assertContainerBuilderHasServiceDefinitionWithTag(SingleServerHandler::class, 'schedule.extension_handler');
128
    }
129
130
    /**
131
     * @test
132
     */
133
    public function can_configure_without_overlapping_handler_lock_factory()
134
    {
135
        $this->load(['without_overlapping_lock_factory' => 'my_factory']);
136
137
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(WithoutOverlappingHandler::class, 0, 'my_factory');
138
        $this->assertContainerBuilderHasServiceDefinitionWithTag(WithoutOverlappingHandler::class, 'schedule.extension_handler');
139
    }
140
141
    /**
142
     * @test
143
     */
144
    public function can_configure_http_client()
145
    {
146
        $this->load(['http_client' => 'my_client']);
147
148
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(PingHandler::class, 0, 'my_client');
149
        $this->assertContainerBuilderHasServiceDefinitionWithTag(PingHandler::class, 'schedule.extension_handler');
150
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(PingTaskRunner::class, 0, 'my_client');
151
        $this->assertContainerBuilderHasServiceDefinitionWithTag(PingTaskRunner::class, 'schedule.task_runner');
152
    }
153
154
    /**
155
     * @test
156
     */
157
    public function can_enable_messenger_with_default_bus(): void
158
    {
159
        $this->load(['messenger' => null]);
160
161
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(MessageTaskRunner::class, 0, 'message_bus');
162
        $this->assertContainerBuilderHasServiceDefinitionWithTag(MessageTaskRunner::class, 'schedule.task_runner');
163
    }
164
165
    /**
166
     * @test
167
     */
168
    public function can_enable_messenger_with_custom_bus(): void
169
    {
170
        $this->load(['messenger' => ['message_bus' => 'my_bus']]);
171
172
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(MessageTaskRunner::class, 0, 'my_bus');
173
        $this->assertContainerBuilderHasServiceDefinitionWithTag(MessageTaskRunner::class, 'schedule.task_runner');
174
    }
175
176
    /**
177
     * @test
178
     */
179
    public function can_configure_email_handler()
180
    {
181
        $this->load(['mailer' => [
182
            'service' => 'my_mailer',
183
            'default_from' => '[email protected]',
184
            'default_to' => '[email protected]',
185
            'subject_prefix' => '[Acme Inc]',
186
        ]]);
187
188
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 0, 'my_mailer');
189
        $this->assertContainerBuilderHasServiceDefinitionWithTag(EmailHandler::class, 'schedule.extension_handler');
190
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 1, '[email protected]');
191
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 2, '[email protected]');
192
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 3, '[Acme Inc]');
193
    }
194
195
    /**
196
     * @test
197
     */
198
    public function minimum_email_handler_configuration()
199
    {
200
        $this->load(['mailer' => [
201
            'service' => 'my_mailer',
202
        ]]);
203
204
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 0, 'my_mailer');
205
        $this->assertContainerBuilderHasServiceDefinitionWithTag(EmailHandler::class, 'schedule.extension_handler');
206
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 1, null);
207
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 2, null);
208
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 3, null);
209
    }
210
211
    /**
212
     * @test
213
     */
214
    public function can_add_schedule_environment_as_string()
215
    {
216
        $this->load(['schedule_extensions' => [
217
            'environments' => 'prod',
218
        ]]);
219
220
        $this->assertContainerBuilderHasService('zenstruck_schedule.extension.environments', EnvironmentExtension::class);
221
        $this->assertContainerBuilderHasServiceDefinitionWithArgument('zenstruck_schedule.extension.environments', 0, ['prod']);
222
        $this->assertContainerBuilderHasServiceDefinitionWithTag('zenstruck_schedule.extension.environments', 'schedule.extension');
223
224
        $extensionIterator = $this->container->getDefinition(ScheduleExtensionSubscriber::class)->getArgument(0);
225
226
        $this->assertInstanceOf(TaggedIteratorArgument::class, $extensionIterator);
227
        $this->assertSame('schedule.extension', $extensionIterator->getTag());
228
    }
229
230
    /**
231
     * @test
232
     */
233
    public function can_add_schedule_environment_as_array()
234
    {
235
        $this->load(['schedule_extensions' => [
236
            'environments' => ['prod', 'stage'],
237
        ]]);
238
239
        $this->assertContainerBuilderHasServiceDefinitionWithArgument('zenstruck_schedule.extension.environments', 0, ['prod', 'stage']);
240
    }
241
242
    /**
243
     * @test
244
     */
245
    public function can_enable_single_server_schedule_extension()
246
    {
247
        $this->load(['schedule_extensions' => [
248
            'on_single_server' => null,
249
        ]]);
250
251
        $this->assertContainerBuilderHasService('zenstruck_schedule.extension.on_single_server', SingleServerExtension::class);
252
        $this->assertContainerBuilderHasServiceDefinitionWithTag('zenstruck_schedule.extension.on_single_server', 'schedule.extension');
253
254
        $extensionIterator = $this->container->getDefinition(ScheduleExtensionSubscriber::class)->getArgument(0);
255
256
        $this->assertInstanceOf(TaggedIteratorArgument::class, $extensionIterator);
257
        $this->assertSame('schedule.extension', $extensionIterator->getTag());
258
    }
259
260
    /**
261
     * @test
262
     */
263
    public function can_enable_email_on_failure_schedule_extension()
264
    {
265
        $this->load(['schedule_extensions' => [
266
            'email_on_failure' => [
267
                'to' => '[email protected]',
268
                'subject' => 'my subject',
269
            ],
270
        ]]);
271
272
        $this->assertContainerBuilderHasService('zenstruck_schedule.extension.email_on_failure', EmailExtension::class);
273
        $this->assertContainerBuilderHasServiceDefinitionWithTag('zenstruck_schedule.extension.email_on_failure', 'schedule.extension');
274
275
        $definition = $this->container->getDefinition('zenstruck_schedule.extension.email_on_failure');
276
277
        $this->assertSame([EmailExtension::class, 'scheduleFailure'], $definition->getFactory());
278
        $this->assertSame(['[email protected]', 'my subject'], $definition->getArguments());
279
280
        $extensionIterator = $this->container->getDefinition(ScheduleExtensionSubscriber::class)->getArgument(0);
281
282
        $this->assertInstanceOf(TaggedIteratorArgument::class, $extensionIterator);
283
        $this->assertSame('schedule.extension', $extensionIterator->getTag());
284
    }
285
286
    /**
287
     * @test
288
     * @dataProvider pingScheduleExtensionProvider
289
     */
290
    public function can_enable_ping_schedule_extensions($key, $method)
291
    {
292
        $this->load(['schedule_extensions' => [
293
            $key => [
294
                'url' => 'example.com',
295
            ],
296
        ]]);
297
298
        $this->assertContainerBuilderHasService('zenstruck_schedule.extension.'.$key, PingExtension::class);
299
        $this->assertContainerBuilderHasServiceDefinitionWithTag('zenstruck_schedule.extension.'.$key, 'schedule.extension');
300
301
        $definition = $this->container->getDefinition('zenstruck_schedule.extension.'.$key);
302
303
        $this->assertSame([PingExtension::class, $method], $definition->getFactory());
304
        $this->assertSame(['example.com', 'GET', []], $definition->getArguments());
305
306
        $extensionIterator = $this->container->getDefinition(ScheduleExtensionSubscriber::class)->getArgument(0);
307
308
        $this->assertInstanceOf(TaggedIteratorArgument::class, $extensionIterator);
309
        $this->assertSame('schedule.extension', $extensionIterator->getTag());
310
    }
311
312
    public static function pingScheduleExtensionProvider()
313
    {
314
        return [
315
            ['ping_before', 'scheduleBefore'],
316
            ['ping_after', 'scheduleAfter'],
317
            ['ping_on_success', 'scheduleSuccess'],
318
            ['ping_on_failure', 'scheduleFailure'],
319
        ];
320
    }
321
322
    /**
323
     * @test
324
     */
325
    public function minimum_task_configuration()
326
    {
327
        $this->load([
328
            'tasks' => [
329
                [
330
                    'task' => 'my:command',
331
                    'frequency' => '0 * * * *',
332
                ],
333
            ],
334
        ]);
335
336
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
337
338
        $this->assertSame(['my:command'], $config['task']);
339
        $this->assertSame('0 * * * *', $config['frequency']);
340
        $this->assertNull($config['description']);
341
        $this->assertNull($config['timezone']);
342
        $this->assertFalse($config['without_overlapping']['enabled']);
343
        $this->assertFalse($config['only_between']['enabled']);
344
        $this->assertFalse($config['unless_between']['enabled']);
345
        $this->assertFalse($config['ping_before']['enabled']);
346
        $this->assertFalse($config['ping_after']['enabled']);
347
        $this->assertFalse($config['ping_on_success']['enabled']);
348
        $this->assertFalse($config['ping_on_failure']['enabled']);
349
        $this->assertFalse($config['email_after']['enabled']);
350
        $this->assertFalse($config['email_on_failure']['enabled']);
351
    }
352
353
    /**
354
     * @test
355
     */
356
    public function can_configure_a_compound_task()
357
    {
358
        $this->load([
359
            'tasks' => [
360
                [
361
                    'task' => ['my:command', 'bash:/my-script'],
362
                    'frequency' => '0 * * * *',
363
                ],
364
            ],
365
        ]);
366
367
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
368
369
        $this->assertSame(['my:command', 'bash:/my-script'], $config['task']);
370
    }
371
372
    /**
373
     * @test
374
     */
375
    public function can_configure_a_compound_task_with_descriptions()
376
    {
377
        $this->load([
378
            'tasks' => [
379
                [
380
                    'task' => [
381
                        'task1' => 'my:command',
382
                        'task2' => 'bash:/my-script',
383
                    ],
384
                    'frequency' => '0 * * * *',
385
                ],
386
            ],
387
        ]);
388
389
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
390
391
        $this->assertSame(['task1' => 'my:command', 'task2' => 'bash:/my-script'], $config['task']);
392
    }
393
394
    /**
395
     * @test
396
     */
397
    public function compound_tasks_cannot_be_an_empty_array()
398
    {
399
        $this->expectException(InvalidConfigurationException::class);
400
        $this->expectExceptionMessage('The path "zenstruck_schedule.tasks.0.task" should have at least 1 element(s) defined.');
401
402
        $this->load([
403
            'tasks' => [
404
                [
405
                    'task' => [],
406
                    'frequency' => 'invalid',
407
                ],
408
            ],
409
        ]);
410
    }
411
412
    /**
413
     * @test
414
     */
415
    public function task_is_required()
416
    {
417
        $this->expectException(InvalidConfigurationException::class);
418
        $this->expectExceptionMessage('"task"');
419
420
        $this->load([
421
            'tasks' => [
422
                [
423
                    'frequency' => '0 * * * *',
424
                ],
425
            ],
426
        ]);
427
    }
428
429
    /**
430
     * @test
431
     */
432
    public function task_cannot_be_null()
433
    {
434
        $this->expectException(InvalidConfigurationException::class);
435
        $this->expectExceptionMessage('Invalid configuration for path "zenstruck_schedule.tasks.0.task": Task cannot be empty value.');
436
437
        $this->load([
438
            'tasks' => [
439
                [
440
                    'task' => null,
441
                    'frequency' => '0 * * * *',
442
                ],
443
            ],
444
        ]);
445
    }
446
447
    /**
448
     * @test
449
     */
450
    public function task_cannot_be_empty()
451
    {
452
        $this->expectException(InvalidConfigurationException::class);
453
        $this->expectExceptionMessage('Invalid configuration for path "zenstruck_schedule.tasks.0.task": Task cannot be empty value.');
454
455
        $this->load([
456
            'tasks' => [
457
                [
458
                    'task' => '',
459
                    'frequency' => '0 * * * *',
460
                ],
461
            ],
462
        ]);
463
    }
464
465
    /**
466
     * @test
467
     */
468
    public function compound_tasks_must_not_contain_null_values()
469
    {
470
        $this->expectException(InvalidConfigurationException::class);
471
        $this->expectExceptionMessage('Invalid configuration for path "zenstruck_schedule.tasks.0.task": Task cannot be empty value.');
472
473
        $this->load([
474
            'tasks' => [
475
                [
476
                    'task' => ['my:command', null],
477
                    'frequency' => 'invalid',
478
                ],
479
            ],
480
        ]);
481
    }
482
483
    /**
484
     * @test
485
     */
486
    public function task_frequency_is_required()
487
    {
488
        $this->expectException(InvalidConfigurationException::class);
489
        $this->expectExceptionMessage('"frequency"');
490
491
        $this->load([
492
            'tasks' => [
493
                [
494
                    'task' => 'my:command',
495
                ],
496
            ],
497
        ]);
498
    }
499
500
    /**
501
     * @test
502
     */
503
    public function task_frequency_cannot_be_null()
504
    {
505
        $this->expectException(InvalidConfigurationException::class);
506
        $this->expectExceptionMessage('The path "zenstruck_schedule.tasks.0.frequency" cannot contain an empty value, but got null.');
507
508
        $this->load([
509
            'tasks' => [
510
                [
511
                    'task' => 'my:command',
512
                    'frequency' => null,
513
                ],
514
            ],
515
        ]);
516
    }
517
518
    /**
519
     * @test
520
     */
521
    public function task_frequency_must_be_valid()
522
    {
523
        $this->expectException(InvalidConfigurationException::class);
524
        $this->expectExceptionMessage('Invalid configuration for path "zenstruck_schedule.tasks.0.frequency": "invalid" is an invalid cron expression.');
525
526
        $this->load([
527
            'tasks' => [
528
                [
529
                    'task' => 'my:command',
530
                    'frequency' => 'invalid',
531
                ],
532
            ],
533
        ]);
534
    }
535
536
    /**
537
     * @test
538
     */
539
    public function can_use_extended_frequency_expression()
540
    {
541
        $this->load([
542
            'tasks' => [
543
                [
544
                    'task' => 'my:command',
545
                    'frequency' => '@daily',
546
                ],
547
            ],
548
        ]);
549
550
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
551
552
        $this->assertSame('@daily', $config['frequency']);
553
    }
554
555
    /**
556
     * @test
557
     */
558
    public function can_use_hashed_frequency_expression()
559
    {
560
        $this->load([
561
            'tasks' => [
562
                [
563
                    'task' => 'my:command',
564
                    'frequency' => 'H H * * *',
565
                ],
566
            ],
567
        ]);
568
569
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
570
571
        $this->assertSame('H H * * *', $config['frequency']);
572
    }
573
574
    /**
575
     * @test
576
     */
577
    public function can_use_frequency_alias()
578
    {
579
        $this->load([
580
            'tasks' => [
581
                [
582
                    'task' => 'my:command',
583
                    'frequency' => '#midnight',
584
                ],
585
            ],
586
        ]);
587
588
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
589
590
        $this->assertSame('#midnight', $config['frequency']);
591
    }
592
593
    /**
594
     * @test
595
     */
596
    public function full_task_configuration()
597
    {
598
        $this->load([
599
            'tasks' => [
600
                [
601
                    'task' => [
602
                        'my:command --option',
603
                        'another:command',
604
                    ],
605
                    'frequency' => '0 0 * * *',
606
                    'description' => 'my description',
607
                    'timezone' => 'UTC',
608
                    'without_overlapping' => null,
609
                    'only_between' => [
610
                        'start' => 9,
611
                        'end' => 17,
612
                    ],
613
                    'unless_between' => [
614
                        'start' => 12,
615
                        'end' => '13:30',
616
                    ],
617
                    'ping_before' => [
618
                        'url' => 'https://example.com/before',
619
                    ],
620
                    'ping_after' => [
621
                        'url' => 'https://example.com/after',
622
                    ],
623
                    'ping_on_success' => [
624
                        'url' => 'https://example.com/success',
625
                    ],
626
                    'ping_on_failure' => [
627
                        'url' => 'https://example.com/failure',
628
                        'method' => 'POST',
629
                    ],
630
                    'email_after' => null,
631
                    'email_on_failure' => [
632
                        'to' => '[email protected]',
633
                        'subject' => 'my subject',
634
                    ],
635
                ],
636
            ],
637
        ]);
638
639
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
640
641
        $this->assertSame(['my:command --option', 'another:command'], $config['task']);
642
        $this->assertSame('0 0 * * *', $config['frequency']);
643
        $this->assertSame('my description', $config['description']);
644
        $this->assertSame('UTC', $config['timezone']);
645
        $this->assertTrue($config['without_overlapping']['enabled']);
646
        $this->assertSame(WithoutOverlappingExtension::DEFAULT_TTL, $config['without_overlapping']['ttl']);
647
        $this->assertTrue($config['only_between']['enabled']);
648
        $this->assertSame(9, $config['only_between']['start']);
649
        $this->assertSame(17, $config['only_between']['end']);
650
        $this->assertTrue($config['unless_between']['enabled']);
651
        $this->assertSame(12, $config['unless_between']['start']);
652
        $this->assertSame('13:30', $config['unless_between']['end']);
653
        $this->assertTrue($config['ping_before']['enabled']);
654
        $this->assertSame('https://example.com/before', $config['ping_before']['url']);
655
        $this->assertSame('GET', $config['ping_before']['method']);
656
        $this->assertTrue($config['ping_after']['enabled']);
657
        $this->assertSame('https://example.com/after', $config['ping_after']['url']);
658
        $this->assertSame('GET', $config['ping_after']['method']);
659
        $this->assertTrue($config['ping_on_success']['enabled']);
660
        $this->assertSame('https://example.com/success', $config['ping_on_success']['url']);
661
        $this->assertSame('GET', $config['ping_on_success']['method']);
662
        $this->assertTrue($config['ping_on_failure']['enabled']);
663
        $this->assertSame('https://example.com/failure', $config['ping_on_failure']['url']);
664
        $this->assertSame('POST', $config['ping_on_failure']['method']);
665
        $this->assertTrue($config['email_after']['enabled']);
666
        $this->assertNull($config['email_after']['to']);
667
        $this->assertNull($config['email_after']['subject']);
668
        $this->assertTrue($config['email_on_failure']['enabled']);
669
        $this->assertSame('[email protected]', $config['email_on_failure']['to']);
670
        $this->assertSame('my subject', $config['email_on_failure']['subject']);
671
    }
672
673
    /**
674
     * @test
675
     */
676
    public function email_and_ping_configuration_can_be_shortened()
677
    {
678
        $this->load([
679
            'tasks' => [
680
                [
681
                    'task' => 'my:command --option',
682
                    'frequency' => '0 0 * * *',
683
                    'ping_after' => 'https://example.com/after',
684
                    'email_after' => '[email protected]',
685
                ],
686
            ],
687
        ]);
688
689
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
690
691
        $this->assertTrue($config['ping_after']['enabled']);
692
        $this->assertSame('https://example.com/after', $config['ping_after']['url']);
693
        $this->assertSame('GET', $config['ping_after']['method']);
694
        $this->assertSame([], $config['ping_after']['options']);
695
696
        $this->assertTrue($config['email_after']['enabled']);
697
        $this->assertSame('[email protected]', $config['email_after']['to']);
698
        $this->assertNull($config['email_after']['subject']);
699
    }
700
701
    /**
702
     * @test
703
     */
704
    public function between_and_unless_between_config_can_be_shortened()
705
    {
706
        $this->load([
707
            'tasks' => [
708
                [
709
                    'task' => 'my:command --option',
710
                    'frequency' => '0 0 * * *',
711
                    'only_between' => '9-17',
712
                    'unless_between' => '11:30-13:15',
713
                ],
714
            ],
715
        ]);
716
717
        $config = $this->container->getDefinition(TaskConfigurationSubscriber::class)->getArgument(0)[0];
718
719
        $this->assertTrue($config['only_between']['enabled']);
720
        $this->assertSame('9', $config['only_between']['start']);
721
        $this->assertSame('17', $config['only_between']['end']);
722
723
        $this->assertTrue($config['unless_between']['enabled']);
724
        $this->assertSame('11:30', $config['unless_between']['start']);
725
        $this->assertSame('13:15', $config['unless_between']['end']);
726
    }
727
728
    protected function getContainerExtensions(): array
729
    {
730
        return [new ZenstruckScheduleExtension()];
731
    }
732
}
733