diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -419,6 +419,7 @@ 'DifferentialReleephRequestFieldSpecification' => 'applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php', 'DifferentialRemarkupRule' => 'applications/differential/remarkup/DifferentialRemarkupRule.php', 'DifferentialReplyHandler' => 'applications/differential/mail/DifferentialReplyHandler.php', + 'DifferentialReplyHandlerTestCase' => 'applications/differential/mail/__tests__/DifferentialReplyHandlerTestCase.php', 'DifferentialRepositoryField' => 'applications/differential/customfield/DifferentialRepositoryField.php', 'DifferentialRepositoryLookup' => 'applications/differential/query/DifferentialRepositoryLookup.php', 'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php', @@ -3102,6 +3103,7 @@ 'DifferentialProjectReviewersField' => 'DifferentialCustomField', 'DifferentialRemarkupRule' => 'PhabricatorRemarkupRuleObject', 'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler', + 'DifferentialReplyHandlerTestCase' => 'PhabricatorTestCase', 'DifferentialRepositoryField' => 'DifferentialCoreCustomField', 'DifferentialRepositoryLookup' => 'Phobject', 'DifferentialResultsTableView' => 'AphrontView', diff --git a/src/applications/differential/mail/DifferentialReplyHandler.php b/src/applications/differential/mail/DifferentialReplyHandler.php --- a/src/applications/differential/mail/DifferentialReplyHandler.php +++ b/src/applications/differential/mail/DifferentialReplyHandler.php @@ -99,19 +99,29 @@ $this->handleAction($mail->getCleanTextBody(), $mail->getAttachments()); } - public function handleAction($body, array $attachments) { + public function extractCommand($body) { // all commands start with a bang and separated from the body by a newline // to make sure that actual feedback text couldn't trigger an action. // unrecognized commands will be parsed as part of the comment. $command = DifferentialAction::ACTION_COMMENT; $supported_commands = $this->getSupportedCommands(); - $regex = "/\A\n*!(" . implode('|', $supported_commands) . ")\n*/"; + $regex = "/(?:\A\s*|\n+\s*)!(". + implode('|', $supported_commands). + ")(?:\s*\z|\s*\n+)/"; + $matches = array(); if (preg_match($regex, $body, $matches)) { $command = $matches[1]; $body = trim(str_replace('!' . $command, '', $body)); } + + return array($command, $body); + } + + public function handleAction($body, array $attachments) { + list($command, $body) = $this->extractCommand($body); + $actor = $this->getActor(); if (!$actor) { throw new Exception('No actor is set for the reply action.'); diff --git a/src/applications/differential/mail/__tests__/DifferentialReplyHandlerTestCase.php b/src/applications/differential/mail/__tests__/DifferentialReplyHandlerTestCase.php new file mode 100644 --- /dev/null +++ b/src/applications/differential/mail/__tests__/DifferentialReplyHandlerTestCase.php @@ -0,0 +1,36 @@ +extractCommand("!reject\ntext"); + $this->assertEqual('reject', $command); + $this->assertEqual('text', $body); + + list($command, $body) = $handler->extractCommand('!reject'); + $this->assertEqual('reject', $command); + $this->assertEqual('', $body); + + list($command, $body) = $handler->extractCommand("hello\n!reject"); + $this->assertEqual('reject', $command); + $this->assertEqual('hello', $body); + + list($command, $body) = + $handler->extractCommand('just chatting about !reject'); + $this->assertEqual(DifferentialAction::ACTION_COMMENT, $command); + $this->assertEqual('just chatting about !reject', $body); + + list($command, $body) = $handler->extractCommand('!reject is awesome'); + $this->assertEqual(DifferentialAction::ACTION_COMMENT, $command); + $this->assertEqual('!reject is awesome', $body); + + list($command, $body) = $handler->extractCommand('what about !reject ?'); + $this->assertEqual(DifferentialAction::ACTION_COMMENT, $command); + $this->assertEqual('what about !reject ?', $body); + + list($command, $body) = $handler->extractCommand(" !reject\nso awesome"); + $this->assertEqual('reject', $command); + $this->assertEqual('so awesome', $body); + } +}