Passed
Push — master ( 81662d...79e5c8 )
by Kevin
02:02
created

ScheduleListCommandTest.php$3 ➔ normalizeOutput()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
1
<?php
2
3
namespace Zenstruck\ScheduleBundle\Tests\Command;
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\Console\Application;
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Helper\FormatterHelper;
9
use Symfony\Component\Console\Helper\HelperSet;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\Console\Tester\CommandTester;
12
use Zenstruck\ScheduleBundle\Command\ScheduleListCommand;
13
use Zenstruck\ScheduleBundle\Schedule;
14
use Zenstruck\ScheduleBundle\Schedule\Extension\ExtensionHandlerRegistry;
15
use Zenstruck\ScheduleBundle\Schedule\ScheduleBuilder;
16
use Zenstruck\ScheduleBundle\Tests\Fixture\MockScheduleBuilder;
17
18
/**
19
 * @author Kevin Bond <[email protected]>
20
 */
21
final class ScheduleListCommandTest extends TestCase
22
{
23
    /**
24
     * @test
25
     */
26
    public function no_tasks_defined()
27
    {
28
        $runner = (new MockScheduleBuilder())->getRunner();
29
        $commandTester = new CommandTester(new ScheduleListCommand($runner, new ExtensionHandlerRegistry([])));
30
31
        $this->expectException(\RuntimeException::class);
32
        $this->expectExceptionMessage('No scheduled tasks configured.');
33
34
        $commandTester->execute([]);
35
    }
36
37
    /**
38
     * @test
39
     */
40
    public function lists_configured_tasks_and_issues()
41
    {
42
        $runner = (new MockScheduleBuilder())
43
            ->addBuilder(new class() implements ScheduleBuilder {
44
                public function buildSchedule(Schedule $schedule): void
45
                {
46
                    $schedule->emailOnFailure('[email protected]');
47
                    $schedule->addCommand('my:command')
48
                        ->mondays()
49
                        ->at('1:30')
50
                        ->emailOnFailure('[email protected]')
51
                        ->pingOnFailure('https://example.com/my-command-failed')
52
                    ;
53
                }
54
            })
55
            ->getRunner()
56
        ;
57
        $command = new ScheduleListCommand($runner, new ExtensionHandlerRegistry([]));
58
        $command->setHelperSet(new HelperSet([new FormatterHelper()]));
59
        $command->setApplication(new Application());
60
        $commandTester = new CommandTester($command);
61
62
        $commandTester->execute([]);
63
        $output = $this->normalizeOutput($commandTester);
64
65
        $this->assertStringContainsString('[!] CommandTask my:command 2 Every Monday at 1:30am (30 1 * * 1)', $output);
66
        $this->assertStringContainsString('[WARNING] 4 task issues:', $output);
67
        $this->assertStringContainsString('[ERROR] No task runner registered to handle "Zenstruck\ScheduleBundle\Schedule\Task\CommandTask".', $output);
68
        $this->assertStringContainsString('[ERROR] To use the email extension you must configure a mailer (config path: "zenstruck_schedule.email_handler").', $output);
69
        $this->assertStringContainsString('[ERROR] No extension handler registered for "Zenstruck\ScheduleBundle\Schedule\Extension\PingExtension: On Task', $output);
70
        $this->assertStringContainsString('[ERROR] Command "my:command" not registered.', $output);
71
        $this->assertStringContainsString('Failure, ping "https://example.com/my-command-failed"".', $output);
72
        $this->assertStringContainsString('1 Schedule Extension:', $output);
73
        $this->assertStringContainsString('On Schedule Failure, email output to "[email protected]"', $output);
74
        $this->assertStringContainsString('[WARNING] 1 issue with schedule:', $output);
75
    }
76
77
    /**
78
     * @test
79
     */
80
    public function renders_exception_stack_trace_if_verbose()
81
    {
82
        $runner = (new MockScheduleBuilder())
83
            ->addBuilder(new class() implements ScheduleBuilder {
84
                public function buildSchedule(Schedule $schedule): void
85
                {
86
                    $schedule->addCommand('my:command')
87
                        ->mondays()
88
                        ->at('1:30')
89
                    ;
90
                }
91
            })
92
            ->getRunner()
93
        ;
94
        $command = new ScheduleListCommand($runner, new ExtensionHandlerRegistry([]));
95
        $command->setHelperSet(new HelperSet([new FormatterHelper()]));
96
        $command->setApplication(new Application());
97
        $commandTester = new CommandTester($command);
98
99
        $commandTester->execute([], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE]);
100
        $output = $this->normalizeOutput($commandTester);
101
102
        $this->assertStringContainsString('[WARNING] 2 task issues:', $output);
103
        $this->assertStringContainsString('In ScheduleRunner.php line', $output);
104
        $this->assertStringContainsString('[LogicException]', $output);
105
        $this->assertStringContainsString('No task runner registered to handle', $output);
106
        $this->assertStringContainsString('In CommandTask.php line', $output);
107
        $this->assertStringContainsString('[Symfony\Component\Console\Exception\CommandNotFoundException]', $output);
108
        $this->assertStringContainsString('Command "my:command" not registered.', $output);
109
        $this->assertStringContainsString('Exception trace:', $output);
110
    }
111
112
    /**
113
     * @test
114
     */
115
    public function lists_configured_tasks_and_issues_in_detail()
116
    {
117
        $runner = (new MockScheduleBuilder())
118
            ->addBuilder(new class() implements ScheduleBuilder {
119
                public function buildSchedule(Schedule $schedule): void
120
                {
121
                    $schedule->emailOnFailure('[email protected]');
122
                    $schedule->addCommand('my:command')
123
                        ->arguments('arg1', '--option1')
124
                        ->mondays()
125
                        ->at('1:30')
126
                        ->emailOnFailure('[email protected]')
127
                        ->pingOnFailure('https://example.com/my-command-failed')
128
                    ;
129
                }
130
            })
131
            ->getRunner()
132
        ;
133
        $command = new ScheduleListCommand($runner, new ExtensionHandlerRegistry([]));
134
        $command->setHelperSet(new HelperSet([new FormatterHelper()]));
135
        $command->setApplication(new Application());
136
        $commandTester = new CommandTester($command);
137
138
        $commandTester->execute(['--detail' => null]);
139
        $output = $this->normalizeOutput($commandTester);
140
141
        $this->assertStringContainsString('1 Scheduled Tasks Configured', $output);
142
        $this->assertStringContainsString('(1/1) CommandTask: my:command', $output);
143
        $this->assertStringContainsString('Every Monday at 1:30am (30 1 * * 1)', $output);
144
        $this->assertStringContainsString('Mon,', $output);
145
        $this->assertStringContainsString('Arguments: arg1 --option1', $output);
146
        $this->assertStringContainsString('2 Task Extensions:', $output);
147
        $this->assertStringContainsString('On Task Failure, email output to "[email protected]"', $output);
148
        $this->assertStringContainsString('On Task Failure, ping "https://example.com/my-command-failed"', $output);
149
        $this->assertStringContainsString('[WARNING] 4 issues with this task:', $output);
150
        $this->assertStringContainsString('[ERROR] No task runner registered to handle "Zenstruck\ScheduleBundle\Schedule\Task\CommandTask".', $output);
151
        $this->assertStringContainsString('[ERROR] To use the email extension you must configure a mailer (config path: "zenstruck_schedule.email_handler").', $output);
152
        $this->assertStringContainsString('[ERROR] No extension handler registered for "Zenstruck\ScheduleBundle\Schedule\Extension\PingExtension: On Task', $output);
153
        $this->assertStringContainsString('[ERROR] Command "my:command" not registered.', $output);
154
        $this->assertStringContainsString('Failure, ping "https://example.com/my-command-failed"".', $output);
155
        $this->assertStringContainsString('1 Schedule Extension:', $output);
156
        $this->assertStringContainsString('On Schedule Failure, email output to "[email protected]"', $output);
157
        $this->assertStringContainsString('[WARNING] 1 issue with schedule:', $output);
158
    }
159
160
    /**
161
     * @test
162
     */
163
    public function command_task_with_invalid_argument_shows_as_error()
164
    {
165
        $runner = (new MockScheduleBuilder())
166
            ->addTask(new Schedule\Task\CommandTask('my:command -v --option1'))
167
            ->getRunner()
168
        ;
169
170
        $application = new Application();
171
        $application->add(new class() extends Command {
172
            protected static $defaultName = 'my:command';
173
174
            protected function configure()
175
            {
176
                $this->addArgument('arg1');
177
            }
178
        });
179
        $command = new ScheduleListCommand($runner, new ExtensionHandlerRegistry([]));
180
        $command->setHelperSet(new HelperSet([new FormatterHelper()]));
181
        $command->setApplication($application);
182
        $commandTester = new CommandTester($command);
183
184
        $commandTester->execute([]);
185
        $output = $this->normalizeOutput($commandTester);
186
187
        $this->assertStringContainsString('1 Scheduled Tasks Configured', $output);
188
        $this->assertStringContainsString('CommandTask my:command', $output);
189
        $this->assertStringContainsString('[WARNING] 2 task issues:', $output);
190
        $this->assertStringContainsString('[ERROR] The "--option1" option does not exist.', $output);
191
    }
192
193
    private function normalizeOutput(CommandTester $tester): string
194
    {
195
        return \preg_replace('/\s+/', ' ', \str_replace("\n", '', $tester->getDisplay(true)));
196
    }
197
}
198