feature #34980 [Messenger] remove several messages with command messenger:failed:remove (nikophil)

This PR was squashed before being merged into the 5.1-dev branch (closes #34980).

Discussion
----------

[Messenger] remove several messages with command messenger:failed:remove

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | Fix #34940
| License       | MIT

command `messenger:failed:remove` now accepts an array of ids. If several provided, they are not displayed unless option `--show-messages` is passed

Commits
-------

903455e463 [Messenger] remove several messages with command messenger:failed:remove
This commit is contained in:
Fabien Potencier 2020-01-10 12:59:02 +01:00
commit 74feb17927
2 changed files with 74 additions and 20 deletions

View File

@ -35,16 +35,17 @@ class FailedMessagesRemoveCommand extends AbstractFailedMessagesCommand
{
$this
->setDefinition([
new InputArgument('id', InputArgument::REQUIRED, 'Specific message id to remove'),
new InputArgument('id', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Specific message id(s) to remove'),
new InputOption('force', null, InputOption::VALUE_NONE, 'Force the operation without confirmation'),
new InputOption('show-messages', null, InputOption::VALUE_NONE, 'Display messages before removing it (if multiple ids are given)'),
])
->setDescription('Remove a message from the failure transport.')
->setDescription('Remove given messages from the failure transport.')
->setHelp(<<<'EOF'
The <info>%command.name%</info> removes a message that is pending in the failure transport.
The <info>%command.name%</info> removes given messages that are pending in the failure transport.
<info>php %command.full_name% {id}</info>
<info>php %command.full_name% {id1} [{id2} ...]</info>
The specific id can be found via the messenger:failed:show command.
The specific ids can be found via the messenger:failed:show command.
EOF
)
;
@ -60,29 +61,37 @@ EOF
$receiver = $this->getReceiver();
$shouldForce = $input->getOption('force');
$this->removeSingleMessage($input->getArgument('id'), $receiver, $io, $shouldForce);
$ids = $input->getArgument('id');
$shouldDisplayMessages = $input->getOption('show-messages') || 1 === \count($ids);
$this->removeMessages($ids, $receiver, $io, $shouldForce, $shouldDisplayMessages);
return 0;
}
private function removeSingleMessage(string $id, ReceiverInterface $receiver, SymfonyStyle $io, bool $shouldForce)
private function removeMessages(array $ids, ReceiverInterface $receiver, SymfonyStyle $io, bool $shouldForce, bool $shouldDisplayMessages): void
{
if (!$receiver instanceof ListableReceiverInterface) {
throw new RuntimeException(sprintf('The "%s" receiver does not support removing specific messages.', $this->getReceiverName()));
}
$envelope = $receiver->find($id);
if (null === $envelope) {
throw new RuntimeException(sprintf('The message with id "%s" was not found.', $id));
}
$this->displaySingleMessage($envelope, $io);
foreach ($ids as $id) {
$envelope = $receiver->find($id);
if (null === $envelope) {
$io->error(sprintf('The message with id "%s" was not found.', $id));
continue;
}
if ($shouldForce || $io->confirm('Do you want to permanently remove this message?', false)) {
$receiver->reject($envelope);
if ($shouldDisplayMessages) {
$this->displaySingleMessage($envelope, $io);
}
$io->success('Message removed.');
} else {
$io->note('Message not removed.');
if ($shouldForce || $io->confirm('Do you want to permanently remove this message?', false)) {
$receiver->reject($envelope);
$io->success(sprintf('Message with id %s removed.', $id));
} else {
$io->note(sprintf('Message with id %s not removed.', $id));
}
}
}
}

View File

@ -19,7 +19,7 @@ use Symfony\Component\Messenger\Transport\Receiver\ListableReceiverInterface;
class FailedMessagesRemoveCommandTest extends TestCase
{
public function testBasicRun()
public function testRemoveUniqueMessage()
{
$receiver = $this->createMock(ListableReceiverInterface::class);
$receiver->expects($this->once())->method('find')->with(20)->willReturn(new Envelope(new \stdClass()));
@ -30,8 +30,53 @@ class FailedMessagesRemoveCommandTest extends TestCase
);
$tester = new CommandTester($command);
$tester->execute(['id' => 20, '--force' => true]);
$tester->execute(['id' => [20], '--force' => true]);
$this->assertStringContainsString('Message removed.', $tester->getDisplay());
$this->assertStringContainsString('Failed Message Details', $tester->getDisplay());
$this->assertStringContainsString('Message with id 20 removed.', $tester->getDisplay());
}
public function testRemoveMultipleMessages()
{
$receiver = $this->createMock(ListableReceiverInterface::class);
$receiver->expects($this->exactly(3))->method('find')->withConsecutive([20], [30], [40])->willReturnOnConsecutiveCalls(
new Envelope(new \stdClass()),
null,
new Envelope(new \stdClass())
);
$command = new FailedMessagesRemoveCommand(
'failure_receiver',
$receiver
);
$tester = new CommandTester($command);
$tester->execute(['id' => [20, 30, 40], '--force' => true]);
$this->assertStringNotContainsString('Failed Message Details', $tester->getDisplay());
$this->assertStringContainsString('Message with id 20 removed.', $tester->getDisplay());
$this->assertStringContainsString('The message with id "30" was not found.', $tester->getDisplay());
$this->assertStringContainsString('Message with id 40 removed.', $tester->getDisplay());
}
public function testRemoveMultipleMessagesAndDisplayMessages()
{
$receiver = $this->createMock(ListableReceiverInterface::class);
$receiver->expects($this->exactly(2))->method('find')->withConsecutive([20], [30])->willReturnOnConsecutiveCalls(
new Envelope(new \stdClass()),
new Envelope(new \stdClass())
);
$command = new FailedMessagesRemoveCommand(
'failure_receiver',
$receiver
);
$tester = new CommandTester($command);
$tester->execute(['id' => [20, 30], '--force' => true, '--show-messages' => true]);
$this->assertStringContainsString('Failed Message Details', $tester->getDisplay());
$this->assertStringContainsString('Message with id 20 removed.', $tester->getDisplay());
$this->assertStringContainsString('Message with id 30 removed.', $tester->getDisplay());
}
}