Passed
Push — master ( 18c542...46352d )
by Kevin
02:34
created

empty_config_loads_default_services()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 24
c 0
b 0
f 0
dl 0
loc 27
rs 9.536
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 Zenstruck\ScheduleBundle\Command\ScheduleListCommand;
8
use Zenstruck\ScheduleBundle\Command\ScheduleRunCommand;
9
use Zenstruck\ScheduleBundle\DependencyInjection\ZenstruckScheduleExtension;
10
use Zenstruck\ScheduleBundle\EventListener\ConfigureScheduleSubscriber;
11
use Zenstruck\ScheduleBundle\EventListener\LogScheduleSubscriber;
12
use Zenstruck\ScheduleBundle\EventListener\ScheduleBuilderSubscriber;
13
use Zenstruck\ScheduleBundle\EventListener\SelfSchedulingSubscriber;
14
use Zenstruck\ScheduleBundle\EventListener\TimezoneSubscriber;
15
use Zenstruck\ScheduleBundle\Schedule\Extension\EmailExtension;
16
use Zenstruck\ScheduleBundle\Schedule\Extension\EnvironmentExtension;
17
use Zenstruck\ScheduleBundle\Schedule\Extension\ExtensionHandlerRegistry;
18
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\EmailHandler;
19
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\EnvironmentHandler;
20
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\PingHandler;
21
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\SelfHandlingHandler;
22
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\SingleServerHandler;
23
use Zenstruck\ScheduleBundle\Schedule\Extension\Handler\WithoutOverlappingHandler;
24
use Zenstruck\ScheduleBundle\Schedule\Extension\PingExtension;
25
use Zenstruck\ScheduleBundle\Schedule\Extension\SingleServerExtension;
26
use Zenstruck\ScheduleBundle\Schedule\ScheduleRunner;
27
use Zenstruck\ScheduleBundle\Schedule\Task\Runner\CommandTaskRunner;
28
use Zenstruck\ScheduleBundle\Schedule\Task\Runner\SelfRunningTaskRunner;
29
30
/**
31
 * @author Kevin Bond <[email protected]>
32
 */
33
final class ZenstruckScheduleExtensionTest extends AbstractExtensionTestCase
34
{
35
    /**
36
     * @test
37
     */
38
    public function empty_config_loads_default_services()
39
    {
40
        $this->load([]);
41
42
        $this->assertContainerBuilderHasService(ScheduleListCommand::class);
43
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleListCommand::class, 'console.command');
44
        $this->assertContainerBuilderHasService(ScheduleRunCommand::class);
45
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleRunCommand::class, 'console.command');
46
        $this->assertContainerBuilderHasService(ScheduleRunner::class);
47
        $this->assertContainerBuilderHasService(ScheduleBuilderSubscriber::class);
48
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ScheduleBuilderSubscriber::class, 'kernel.event_subscriber');
49
        $this->assertContainerBuilderHasService(ConfigureScheduleSubscriber::class);
50
        $this->assertContainerBuilderHasServiceDefinitionWithTag(ConfigureScheduleSubscriber::class, 'kernel.event_subscriber');
51
        $this->assertContainerBuilderHasService(SelfSchedulingSubscriber::class);
52
        $this->assertContainerBuilderHasServiceDefinitionWithTag(SelfSchedulingSubscriber::class, 'kernel.event_subscriber');
53
        $this->assertContainerBuilderHasService(CommandTaskRunner::class);
54
        $this->assertContainerBuilderHasServiceDefinitionWithTag(CommandTaskRunner::class, 'schedule.task_runner');
55
        $this->assertContainerBuilderHasService(SelfRunningTaskRunner::class);
56
        $this->assertContainerBuilderHasServiceDefinitionWithTag(SelfRunningTaskRunner::class, 'schedule.task_runner');
57
        $this->assertContainerBuilderHasService(LogScheduleSubscriber::class);
58
        $this->assertContainerBuilderHasServiceDefinitionWithTag(LogScheduleSubscriber::class, 'kernel.event_subscriber');
59
        $this->assertContainerBuilderHasServiceDefinitionWithTag(LogScheduleSubscriber::class, 'monolog.logger', ['channel' => 'schedule']);
60
        $this->assertContainerBuilderHasService(ExtensionHandlerRegistry::class);
61
        $this->assertContainerBuilderHasService(SelfHandlingHandler::class);
62
        $this->assertContainerBuilderHasServiceDefinitionWithTag(SelfHandlingHandler::class, 'schedule.extension_handler', ['priority' => -100]);
63
        $this->assertContainerBuilderHasService(EnvironmentHandler::class);
64
        $this->assertContainerBuilderHasServiceDefinitionWithTag(EnvironmentHandler::class, 'schedule.extension_handler');
65
    }
66
67
    /**
68
     * @test
69
     */
70
    public function can_configure_default_timezone()
71
    {
72
        $this->load(['timezone' => 'UTC']);
73
74
        $this->assertContainerBuilderHasService(TimezoneSubscriber::class);
75
        $this->assertContainerBuilderHasServiceDefinitionWithTag(TimezoneSubscriber::class, 'kernel.event_subscriber');
76
    }
77
78
    /**
79
     * @test
80
     */
81
    public function timezone_must_be_valid()
82
    {
83
        $this->expectException(InvalidConfigurationException::class);
84
        $this->expectExceptionMessage('Invalid configuration for path "zenstruck_schedule.timezone": Timezone "invalid" is not available');
85
86
        $this->load(['timezone' => 'invalid']);
87
    }
88
89
    /**
90
     * @test
91
     */
92
    public function can_configure_single_server_lock_factory()
93
    {
94
        $this->load(['single_server_handler' => 'my_factory']);
95
96
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(SingleServerHandler::class, 0, 'my_factory');
97
        $this->assertContainerBuilderHasServiceDefinitionWithTag(SingleServerHandler::class, 'schedule.extension_handler');
98
    }
99
100
    /**
101
     * @test
102
     */
103
    public function can_configure_without_overlapping_handler_lock_factory()
104
    {
105
        $this->load(['without_overlapping_handler' => 'my_factory']);
106
107
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(WithoutOverlappingHandler::class, 0, 'my_factory');
108
        $this->assertContainerBuilderHasServiceDefinitionWithTag(WithoutOverlappingHandler::class, 'schedule.extension_handler');
109
    }
110
111
    /**
112
     * @test
113
     */
114
    public function can_configure_ping_handler_http_client()
115
    {
116
        $this->load(['ping_handler' => 'my_client']);
117
118
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(PingHandler::class, 0, 'my_client');
119
        $this->assertContainerBuilderHasServiceDefinitionWithTag(PingHandler::class, 'schedule.extension_handler');
120
    }
121
122
    /**
123
     * @test
124
     */
125
    public function can_configure_email_handler()
126
    {
127
        $this->load(['email_handler' => [
128
            'service' => 'my_mailer',
129
            'default_from' => '[email protected]',
130
            'default_to' => '[email protected]',
131
        ]]);
132
133
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 0, 'my_mailer');
134
        $this->assertContainerBuilderHasServiceDefinitionWithTag(EmailHandler::class, 'schedule.extension_handler');
135
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 1, '%zenstruck_schedule.email_handler.default_from%');
136
        $this->assertContainerBuilderHasServiceDefinitionWithArgument(EmailHandler::class, 2, '%zenstruck_schedule.email_handler.default_to%');
137
        $this->assertContainerBuilderHasParameter('zenstruck_schedule.email_handler.default_from', '[email protected]');
138
        $this->assertContainerBuilderHasParameter('zenstruck_schedule.email_handler.default_to', '[email protected]');
139
    }
140
141
    /**
142
     * @test
143
     */
144
    public function can_add_schedule_environment_as_string()
145
    {
146
        $this->load(['schedule_extensions' => [
147
            'environments' => 'prod',
148
        ]]);
149
150
        $this->assertContainerBuilderHasService('zenstruck_schedule.extension.environments', EnvironmentExtension::class);
151
        $this->assertContainerBuilderHasServiceDefinitionWithArgument('zenstruck_schedule.extension.environments', 0, ['prod']);
152
        $this->assertContainerBuilderHasServiceDefinitionWithTag('zenstruck_schedule.extension.environments', 'schedule.configured_extension');
153
    }
154
155
    /**
156
     * @test
157
     */
158
    public function can_add_schedule_environment_as_array()
159
    {
160
        $this->load(['schedule_extensions' => [
161
            'environments' => ['prod', 'stage'],
162
        ]]);
163
164
        $this->assertContainerBuilderHasServiceDefinitionWithArgument('zenstruck_schedule.extension.environments', 0, ['prod', 'stage']);
165
    }
166
167
    /**
168
     * @test
169
     */
170
    public function can_enable_single_server_schedule_extension()
171
    {
172
        $this->load(['schedule_extensions' => [
173
            'on_single_server' => null,
174
        ]]);
175
176
        $this->assertContainerBuilderHasService('zenstruck_schedule.extension.on_single_server', SingleServerExtension::class);
177
        $this->assertContainerBuilderHasServiceDefinitionWithTag('zenstruck_schedule.extension.on_single_server', 'schedule.configured_extension');
178
    }
179
180
    /**
181
     * @test
182
     */
183
    public function can_enable_email_on_failure_schedule_extension()
184
    {
185
        $this->load(['schedule_extensions' => [
186
            'email_on_failure' => [
187
                'to' => '[email protected]',
188
                'subject' => 'my subject',
189
            ],
190
        ]]);
191
192
        $this->assertContainerBuilderHasService('zenstruck_schedule.extension.email_on_failure', EmailExtension::class);
193
        $this->assertContainerBuilderHasServiceDefinitionWithTag('zenstruck_schedule.extension.email_on_failure', 'schedule.configured_extension');
194
195
        $definition = $this->container->getDefinition('zenstruck_schedule.extension.email_on_failure');
196
197
        $this->assertSame([EmailExtension::class, 'scheduleFailure'], $definition->getFactory());
198
        $this->assertSame(['[email protected]', 'my subject'], $definition->getArguments());
199
    }
200
201
    /**
202
     * @test
203
     * @dataProvider pingScheduleExtensionProvider
204
     */
205
    public function can_enable_ping_schedule_extensions($key, $method)
206
    {
207
        $this->load(['schedule_extensions' => [
208
            $key => [
209
                'url' => 'example.com',
210
            ],
211
        ]]);
212
213
        $this->assertContainerBuilderHasService('zenstruck_schedule.extension.'.$key, PingExtension::class);
214
        $this->assertContainerBuilderHasServiceDefinitionWithTag('zenstruck_schedule.extension.'.$key, 'schedule.configured_extension');
215
216
        $definition = $this->container->getDefinition('zenstruck_schedule.extension.'.$key);
217
218
        $this->assertSame([PingExtension::class, $method], $definition->getFactory());
219
        $this->assertSame(['example.com', 'GET', []], $definition->getArguments());
220
    }
221
222
    public static function pingScheduleExtensionProvider()
223
    {
224
        return [
225
            ['ping_before', 'scheduleBefore'],
226
            ['ping_after', 'scheduleAfter'],
227
            ['ping_on_success', 'scheduleSuccess'],
228
            ['ping_on_failure', 'scheduleFailure'],
229
        ];
230
    }
231
232
    protected function getContainerExtensions(): array
233
    {
234
        return [new ZenstruckScheduleExtension()];
235
    }
236
}
237