Passed
Pull Request — master (#3)
by Kevin
02:01
created

can_use_frequency_alias()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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