Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 781508d

Browse filesBrowse files
committed
feature #43663 [Messenger] Add command completion for failed messages (scyzoryck)
This PR was merged into the 5.4 branch. Discussion ---------- [Messenger] Add command completion for failed messages | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | #43594 | License | MIT | Doc PR | no Add command completion for failed messages. Commits ------- a01a895 [Messenger] Add completion for failed messages commands.
2 parents aa68efc + a01a895 commit 781508d
Copy full SHA for 781508d
Expand file treeCollapse file tree

8 files changed

+268
-6
lines changed

‎.php-cs-fixer.dist.php

Copy file name to clipboardExpand all lines: .php-cs-fixer.dist.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
->notPath('Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Custom/_name_entry_label.html.php')
4242
// explicit trigger_error tests
4343
->notPath('Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php')
44+
// stop removing spaces on the end of the line in strings
45+
->notPath('Symfony/Component/Messenger/Tests/Command/FailedMessagesShowCommandTest.php')
4446
)
4547
->setCacheFile('.php-cs-fixer.cache')
4648
;

‎src/Symfony/Component/Messenger/Command/AbstractFailedMessagesCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Command/AbstractFailedMessagesCommand.php
+32Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Messenger\Command;
1313

1414
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Completion\CompletionInput;
16+
use Symfony\Component\Console\Completion\CompletionSuggestions;
1517
use Symfony\Component\Console\Helper\Dumper;
1618
use Symfony\Component\Console\Question\ChoiceQuestion;
1719
use Symfony\Component\Console\Style\SymfonyStyle;
@@ -23,6 +25,7 @@
2325
use Symfony\Component\Messenger\Stamp\RedeliveryStamp;
2426
use Symfony\Component\Messenger\Stamp\SentToFailureTransportStamp;
2527
use Symfony\Component\Messenger\Stamp\TransportMessageIdStamp;
28+
use Symfony\Component\Messenger\Transport\Receiver\ListableReceiverInterface;
2629
use Symfony\Component\Messenger\Transport\Receiver\MessageCountAwareInterface;
2730
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
2831
use Symfony\Component\VarDumper\Caster\Caster;
@@ -39,6 +42,8 @@
3942
*/
4043
abstract class AbstractFailedMessagesCommand extends Command
4144
{
45+
protected const DEFAULT_TRANSPORT_OPTION = 'choose';
46+
4247
protected $failureTransports;
4348

4449
private $globalFailureReceiverName;
@@ -263,4 +268,31 @@ protected function interactiveChooseFailureTransport(SymfonyStyle $io)
263268

264269
return $io->askQuestion($question);
265270
}
271+
272+
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
273+
{
274+
if ($input->mustSuggestOptionValuesFor('transport')) {
275+
$suggestions->suggestValues(array_keys($this->failureTransports->getProvidedServices()));
276+
277+
return;
278+
}
279+
280+
if ($input->mustSuggestArgumentValuesFor('id')) {
281+
$transport = $input->getOption('transport');
282+
$transport = self::DEFAULT_TRANSPORT_OPTION === $transport ? $this->getGlobalFailureReceiverName() : $transport;
283+
$receiver = $this->getReceiver($transport);
284+
285+
if (!$receiver instanceof ListableReceiverInterface) {
286+
return;
287+
}
288+
289+
$ids = [];
290+
foreach ($receiver->all(50) as $envelope) {
291+
$ids[] = $this->getMessageId($envelope);
292+
}
293+
$suggestions->suggestValues($ids);
294+
295+
return;
296+
}
297+
}
266298
}

‎src/Symfony/Component/Messenger/Command/FailedMessagesRemoveCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Command/FailedMessagesRemoveCommand.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ protected function configure(): void
3838
->setDefinition([
3939
new InputArgument('id', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Specific message id(s) to remove'),
4040
new InputOption('force', null, InputOption::VALUE_NONE, 'Force the operation without confirmation'),
41-
new InputOption('transport', null, InputOption::VALUE_OPTIONAL, 'Use a specific failure transport'),
41+
new InputOption('transport', null, InputOption::VALUE_OPTIONAL, 'Use a specific failure transport', self::DEFAULT_TRANSPORT_OPTION),
4242
new InputOption('show-messages', null, InputOption::VALUE_NONE, 'Display messages before removing it (if multiple ids are given)'),
4343
])
4444
->setDescription(self::$defaultDescription)
@@ -61,7 +61,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
6161
$io = new SymfonyStyle($input, $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output);
6262

6363
$failureTransportName = $input->getOption('transport');
64-
if (null === $failureTransportName) {
64+
if (self::DEFAULT_TRANSPORT_OPTION === $failureTransportName) {
6565
$failureTransportName = $this->getGlobalFailureReceiverName();
6666
}
6767

‎src/Symfony/Component/Messenger/Command/FailedMessagesRetryCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Command/FailedMessagesRetryCommand.php
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
*/
3535
class FailedMessagesRetryCommand extends AbstractFailedMessagesCommand
3636
{
37-
private const DEFAULT_TRANSPORT_OPTION = 'choose';
38-
3937
protected static $defaultName = 'messenger:failed:retry';
4038
protected static $defaultDescription = 'Retry one or more messages from the failure transport';
4139

‎src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
*/
2828
class FailedMessagesShowCommand extends AbstractFailedMessagesCommand
2929
{
30-
private const DEFAULT_TRANSPORT_OPTION = 'choose';
31-
3230
protected static $defaultName = 'messenger:failed:show';
3331
protected static $defaultDescription = 'Show one or more messages from the failure transport';
3432

‎src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRemoveCommandTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRemoveCommandTest.php
+76Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
namespace Symfony\Component\Messenger\Tests\Command;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Console\Tester\CommandCompletionTester;
1516
use Symfony\Component\Console\Tester\CommandTester;
1617
use Symfony\Component\DependencyInjection\ServiceLocator;
1718
use Symfony\Component\Messenger\Command\FailedMessagesRemoveCommand;
1819
use Symfony\Component\Messenger\Envelope;
1920
use Symfony\Component\Messenger\Exception\InvalidArgumentException;
21+
use Symfony\Component\Messenger\Stamp\TransportMessageIdStamp;
2022
use Symfony\Component\Messenger\Transport\Receiver\ListableReceiverInterface;
2123

2224
class FailedMessagesRemoveCommandTest extends TestCase
@@ -268,4 +270,78 @@ public function testRemoveMultipleMessagesAndDisplayMessagesWithServiceLocator()
268270
$this->assertStringContainsString('Message with id 20 removed.', $tester->getDisplay());
269271
$this->assertStringContainsString('Message with id 30 removed.', $tester->getDisplay());
270272
}
273+
274+
public function testCompletingTransport()
275+
{
276+
$globalFailureReceiverName = 'failure_receiver';
277+
278+
$receiver = $this->createMock(ListableReceiverInterface::class);
279+
280+
$serviceLocator = $this->createMock(ServiceLocator::class);
281+
$serviceLocator->expects($this->once())->method('getProvidedServices')->willReturn([
282+
'global_receiver' => $receiver,
283+
$globalFailureReceiverName => $receiver,
284+
]);
285+
286+
$command = new FailedMessagesRemoveCommand(
287+
$globalFailureReceiverName,
288+
$serviceLocator
289+
);
290+
$tester = new CommandCompletionTester($command);
291+
292+
$suggestions = $tester->complete(['--transport']);
293+
$this->assertSame(['global_receiver', 'failure_receiver'], $suggestions);
294+
}
295+
296+
public function testCompleteId()
297+
{
298+
$globalFailureReceiverName = 'failure_receiver';
299+
300+
$receiver = $this->createMock(ListableReceiverInterface::class);
301+
$receiver->expects($this->once())->method('all')->with(50)->willReturn([
302+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('2ab50dfa1fbf')]),
303+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('78c2da843723')]),
304+
]);
305+
306+
$serviceLocator = $this->createMock(ServiceLocator::class);
307+
$serviceLocator->expects($this->once())->method('has')->with($globalFailureReceiverName)->willReturn(true);
308+
$serviceLocator->expects($this->any())->method('get')->with($globalFailureReceiverName)->willReturn($receiver);
309+
310+
$command = new FailedMessagesRemoveCommand(
311+
$globalFailureReceiverName,
312+
$serviceLocator
313+
);
314+
$tester = new CommandCompletionTester($command);
315+
316+
$suggestions = $tester->complete(['']);
317+
318+
$this->assertSame(['2ab50dfa1fbf', '78c2da843723'], $suggestions);
319+
}
320+
321+
public function testCompleteIdWithSpecifiedTransport()
322+
{
323+
$globalFailureReceiverName = 'failure_receiver';
324+
$anotherFailureReceiverName = 'another_receiver';
325+
326+
$receiver = $this->createMock(ListableReceiverInterface::class);
327+
$receiver->expects($this->once())->method('all')->with(50)->willReturn([
328+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('2ab50dfa1fbf')]),
329+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('78c2da843723')]),
330+
]);
331+
332+
$serviceLocator = $this->createMock(ServiceLocator::class);
333+
$serviceLocator->expects($this->once())->method('has')->with($anotherFailureReceiverName)->willReturn(true);
334+
$serviceLocator->expects($this->any())->method('get')->with($anotherFailureReceiverName)->willReturn($receiver);
335+
336+
$command = new FailedMessagesRemoveCommand(
337+
$globalFailureReceiverName,
338+
$serviceLocator
339+
);
340+
341+
$tester = new CommandCompletionTester($command);
342+
343+
$suggestions = $tester->complete(['--transport', $anotherFailureReceiverName, ' ']);
344+
345+
$this->assertSame(['2ab50dfa1fbf', '78c2da843723'], $suggestions);
346+
}
271347
}

‎src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRetryCommandTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRetryCommandTest.php
+81Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
namespace Symfony\Component\Messenger\Tests\Command;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Console\Tester\CommandCompletionTester;
1516
use Symfony\Component\Console\Tester\CommandTester;
1617
use Symfony\Component\DependencyInjection\ServiceLocator;
1718
use Symfony\Component\EventDispatcher\EventDispatcher;
1819
use Symfony\Component\Messenger\Command\FailedMessagesRetryCommand;
1920
use Symfony\Component\Messenger\Envelope;
2021
use Symfony\Component\Messenger\MessageBusInterface;
22+
use Symfony\Component\Messenger\Stamp\TransportMessageIdStamp;
2123
use Symfony\Component\Messenger\Transport\Receiver\ListableReceiverInterface;
2224

2325
class FailedMessagesRetryCommandTest extends TestCase
@@ -144,4 +146,83 @@ public function testBasicRunWithServiceLocatorWithSpecificFailureTransport()
144146

145147
$this->assertStringContainsString('[OK]', $tester->getDisplay());
146148
}
149+
150+
public function testCompletingTransport()
151+
{
152+
$globalFailureReceiverName = 'failure_receiver';
153+
154+
$receiver = $this->createMock(ListableReceiverInterface::class);
155+
156+
$serviceLocator = $this->createMock(ServiceLocator::class);
157+
$serviceLocator->expects($this->once())->method('getProvidedServices')->willReturn([
158+
'global_receiver' => $receiver,
159+
$globalFailureReceiverName => $receiver,
160+
]);
161+
162+
$command = new FailedMessagesRetryCommand(
163+
$globalFailureReceiverName,
164+
$serviceLocator,
165+
$this->createMock(MessageBusInterface::class),
166+
new EventDispatcher()
167+
);
168+
$tester = new CommandCompletionTester($command);
169+
170+
$suggestions = $tester->complete(['--transport']);
171+
$this->assertSame(['global_receiver', 'failure_receiver'], $suggestions);
172+
}
173+
174+
public function testCompleteId()
175+
{
176+
$globalFailureReceiverName = 'failure_receiver';
177+
178+
$receiver = $this->createMock(ListableReceiverInterface::class);
179+
$receiver->expects($this->once())->method('all')->with(50)->willReturn([
180+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('2ab50dfa1fbf')]),
181+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('78c2da843723')]),
182+
]);
183+
184+
$serviceLocator = $this->createMock(ServiceLocator::class);
185+
$serviceLocator->expects($this->once())->method('has')->with($globalFailureReceiverName)->willReturn(true);
186+
$serviceLocator->expects($this->any())->method('get')->with($globalFailureReceiverName)->willReturn($receiver);
187+
188+
$command = new FailedMessagesRetryCommand(
189+
$globalFailureReceiverName,
190+
$serviceLocator,
191+
$this->createMock(MessageBusInterface::class),
192+
new EventDispatcher()
193+
);
194+
$tester = new CommandCompletionTester($command);
195+
196+
$suggestions = $tester->complete(['']);
197+
198+
$this->assertSame(['2ab50dfa1fbf', '78c2da843723'], $suggestions);
199+
}
200+
201+
public function testCompleteIdWithSpecifiedTransport()
202+
{
203+
$globalFailureReceiverName = 'failure_receiver';
204+
$anotherFailureReceiverName = 'another_receiver';
205+
206+
$receiver = $this->createMock(ListableReceiverInterface::class);
207+
$receiver->expects($this->once())->method('all')->with(50)->willReturn([
208+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('2ab50dfa1fbf')]),
209+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('78c2da843723')]),
210+
]);
211+
212+
$serviceLocator = $this->createMock(ServiceLocator::class);
213+
$serviceLocator->expects($this->once())->method('has')->with($anotherFailureReceiverName)->willReturn(true);
214+
$serviceLocator->expects($this->any())->method('get')->with($anotherFailureReceiverName)->willReturn($receiver);
215+
216+
$command = new FailedMessagesRetryCommand(
217+
$globalFailureReceiverName,
218+
$serviceLocator,
219+
$this->createMock(MessageBusInterface::class),
220+
new EventDispatcher()
221+
);
222+
$tester = new CommandCompletionTester($command);
223+
224+
$suggestions = $tester->complete(['--transport', $anotherFailureReceiverName, ' ']);
225+
226+
$this->assertSame(['2ab50dfa1fbf', '78c2da843723'], $suggestions);
227+
}
147228
}

‎src/Symfony/Component/Messenger/Tests/Command/FailedMessagesShowCommandTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Tests/Command/FailedMessagesShowCommandTest.php
+75Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Console\Output\OutputInterface;
16+
use Symfony\Component\Console\Tester\CommandCompletionTester;
1617
use Symfony\Component\Console\Tester\CommandTester;
1718
use Symfony\Component\DependencyInjection\ServiceLocator;
1819
use Symfony\Component\Messenger\Command\FailedMessagesShowCommand;
@@ -607,4 +608,78 @@ public function testListMessagesWithServiceLocatorFromSpecificTransport()
607608
$redeliveryStamp->getRedeliveredAt()->format('Y-m-d H:i:s')),
608609
$tester->getDisplay(true));
609610
}
611+
612+
613+
public function testCompletingTransport()
614+
{
615+
$globalFailureReceiverName = 'failure_receiver';
616+
617+
$receiver = $this->createMock(ListableReceiverInterface::class);
618+
619+
$serviceLocator = $this->createMock(ServiceLocator::class);
620+
$serviceLocator->expects($this->once())->method('getProvidedServices')->willReturn([
621+
'global_receiver' => $receiver,
622+
$globalFailureReceiverName => $receiver,
623+
]);
624+
625+
$command = new FailedMessagesShowCommand(
626+
$globalFailureReceiverName,
627+
$serviceLocator
628+
);
629+
$tester = new CommandCompletionTester($command);
630+
631+
$suggestions = $tester->complete(['--transport']);
632+
$this->assertSame(['global_receiver', 'failure_receiver'], $suggestions);
633+
}
634+
635+
public function testCompleteId()
636+
{
637+
$globalFailureReceiverName = 'failure_receiver';
638+
639+
$receiver = $this->createMock(ListableReceiverInterface::class);
640+
$receiver->expects($this->once())->method('all')->with(50)->willReturn([
641+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('2ab50dfa1fbf')]),
642+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('78c2da843723')]),
643+
]);
644+
645+
$serviceLocator = $this->createMock(ServiceLocator::class);
646+
$serviceLocator->expects($this->once())->method('has')->with($globalFailureReceiverName)->willReturn(true);
647+
$serviceLocator->expects($this->any())->method('get')->with($globalFailureReceiverName)->willReturn($receiver);
648+
649+
$command = new FailedMessagesShowCommand(
650+
$globalFailureReceiverName,
651+
$serviceLocator
652+
);
653+
$tester = new CommandCompletionTester($command);
654+
655+
$suggestions = $tester->complete(['']);
656+
657+
$this->assertSame(['2ab50dfa1fbf', '78c2da843723'], $suggestions);
658+
}
659+
660+
public function testCompleteIdWithSpecifiedTransport()
661+
{
662+
$globalFailureReceiverName = 'failure_receiver';
663+
$anotherFailureReceiverName = 'another_receiver';
664+
665+
$receiver = $this->createMock(ListableReceiverInterface::class);
666+
$receiver->expects($this->once())->method('all')->with(50)->willReturn([
667+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('2ab50dfa1fbf')]),
668+
Envelope::wrap(new \stdClass(), [new TransportMessageIdStamp('78c2da843723')]),
669+
]);
670+
671+
$serviceLocator = $this->createMock(ServiceLocator::class);
672+
$serviceLocator->expects($this->once())->method('has')->with($anotherFailureReceiverName)->willReturn(true);
673+
$serviceLocator->expects($this->any())->method('get')->with($anotherFailureReceiverName)->willReturn($receiver);
674+
675+
$command = new FailedMessagesShowCommand(
676+
$globalFailureReceiverName,
677+
$serviceLocator
678+
);
679+
$tester = new CommandCompletionTester($command);
680+
681+
$suggestions = $tester->complete(['--transport', $anotherFailureReceiverName, ' ']);
682+
683+
$this->assertSame(['2ab50dfa1fbf', '78c2da843723'], $suggestions);
684+
}
610685
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.