mirror of
https://github.com/shlinkio/shlink.git
synced 2025-01-21 22:13:15 -06:00
Updated short URL deletion so that it accepts the domain
This commit is contained in:
parent
5f00d8b732
commit
732bb06c62
@ -6,6 +6,7 @@ namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
|
||||
|
||||
use Shlinkio\Shlink\CLI\Util\ExitCodes;
|
||||
use Shlinkio\Shlink\Core\Exception;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\DeleteShortUrlServiceInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
@ -40,33 +41,39 @@ class DeleteShortUrlCommand extends Command
|
||||
InputOption::VALUE_NONE,
|
||||
'Ignores the safety visits threshold check, which could make short URLs with many visits to be '
|
||||
. 'accidentally deleted',
|
||||
)
|
||||
->addOption(
|
||||
'domain',
|
||||
'd',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The domain if the short code does not belong to the default one',
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): ?int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$shortCode = $input->getArgument('shortCode');
|
||||
$identifier = ShortUrlIdentifier::fromCli($input);
|
||||
$ignoreThreshold = $input->getOption('ignore-threshold');
|
||||
|
||||
try {
|
||||
$this->runDelete($io, $shortCode, $ignoreThreshold);
|
||||
$this->runDelete($io, $identifier, $ignoreThreshold);
|
||||
return ExitCodes::EXIT_SUCCESS;
|
||||
} catch (Exception\ShortUrlNotFoundException $e) {
|
||||
$io->error($e->getMessage());
|
||||
return ExitCodes::EXIT_FAILURE;
|
||||
} catch (Exception\DeleteShortUrlException $e) {
|
||||
return $this->retry($io, $shortCode, $e->getMessage());
|
||||
return $this->retry($io, $identifier, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function retry(SymfonyStyle $io, string $shortCode, string $warningMsg): int
|
||||
private function retry(SymfonyStyle $io, ShortUrlIdentifier $identifier, string $warningMsg): int
|
||||
{
|
||||
$io->writeln(sprintf('<bg=yellow>%s</>', $warningMsg));
|
||||
$forceDelete = $io->confirm('Do you want to delete it anyway?', false);
|
||||
|
||||
if ($forceDelete) {
|
||||
$this->runDelete($io, $shortCode, true);
|
||||
$this->runDelete($io, $identifier, true);
|
||||
} else {
|
||||
$io->warning('Short URL was not deleted.');
|
||||
}
|
||||
@ -74,9 +81,9 @@ class DeleteShortUrlCommand extends Command
|
||||
return $forceDelete ? ExitCodes::EXIT_SUCCESS : ExitCodes::EXIT_WARNING;
|
||||
}
|
||||
|
||||
private function runDelete(SymfonyStyle $io, string $shortCode, bool $ignoreThreshold): void
|
||||
private function runDelete(SymfonyStyle $io, ShortUrlIdentifier $identifier, bool $ignoreThreshold): void
|
||||
{
|
||||
$this->deleteShortUrlService->deleteByShortCode($shortCode, $ignoreThreshold);
|
||||
$io->success(sprintf('Short URL with short code "%s" successfully deleted.', $shortCode));
|
||||
$this->deleteShortUrlService->deleteByShortCode($identifier, $ignoreThreshold);
|
||||
$io->success(sprintf('Short URL with short code "%s" successfully deleted.', $identifier->shortCode()));
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +39,10 @@ class DeleteShortUrlCommandTest extends TestCase
|
||||
public function successMessageIsPrintedIfUrlIsProperlyDeleted(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->will(function (): void {
|
||||
});
|
||||
$deleteByShortCode = $this->service->deleteByShortCode(new ShortUrlIdentifier($shortCode), false)->will(
|
||||
function (): void {
|
||||
},
|
||||
);
|
||||
|
||||
$this->commandTester->execute(['shortCode' => $shortCode]);
|
||||
$output = $this->commandTester->getDisplay();
|
||||
@ -56,8 +58,9 @@ class DeleteShortUrlCommandTest extends TestCase
|
||||
public function invalidShortCodePrintsMessage(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow(
|
||||
Exception\ShortUrlNotFoundException::fromNotFound(new ShortUrlIdentifier($shortCode)),
|
||||
$identifier = new ShortUrlIdentifier($shortCode);
|
||||
$deleteByShortCode = $this->service->deleteByShortCode($identifier, false)->willThrow(
|
||||
Exception\ShortUrlNotFoundException::fromNotFound($identifier),
|
||||
);
|
||||
|
||||
$this->commandTester->execute(['shortCode' => $shortCode]);
|
||||
@ -77,7 +80,8 @@ class DeleteShortUrlCommandTest extends TestCase
|
||||
string $expectedMessage
|
||||
): void {
|
||||
$shortCode = 'abc123';
|
||||
$deleteByShortCode = $this->service->deleteByShortCode($shortCode, Argument::type('bool'))->will(
|
||||
$identifier = new ShortUrlIdentifier($shortCode);
|
||||
$deleteByShortCode = $this->service->deleteByShortCode($identifier, Argument::type('bool'))->will(
|
||||
function (array $args) use ($shortCode): void {
|
||||
$ignoreThreshold = array_pop($args);
|
||||
|
||||
@ -110,7 +114,7 @@ class DeleteShortUrlCommandTest extends TestCase
|
||||
public function deleteIsNotRetriedWhenThresholdIsReachedAndQuestionIsDeclined(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow(
|
||||
$deleteByShortCode = $this->service->deleteByShortCode(new ShortUrlIdentifier($shortCode), false)->willThrow(
|
||||
Exception\DeleteShortUrlException::fromVisitsThreshold(10, $shortCode),
|
||||
);
|
||||
$this->commandTester->setInputs(['no']);
|
||||
|
@ -27,9 +27,9 @@ class DeleteShortUrlService implements DeleteShortUrlServiceInterface
|
||||
* @throws Exception\ShortUrlNotFoundException
|
||||
* @throws Exception\DeleteShortUrlException
|
||||
*/
|
||||
public function deleteByShortCode(string $shortCode, bool $ignoreThreshold = false): void
|
||||
public function deleteByShortCode(ShortUrlIdentifier $identifier, bool $ignoreThreshold = false): void
|
||||
{
|
||||
$shortUrl = $this->findByShortCode($this->em, new ShortUrlIdentifier($shortCode));
|
||||
$shortUrl = $this->findByShortCode($this->em, $identifier);
|
||||
if (! $ignoreThreshold && $this->isThresholdReached($shortUrl)) {
|
||||
throw Exception\DeleteShortUrlException::fromVisitsThreshold(
|
||||
$this->deleteShortUrlsOptions->getVisitsThreshold(),
|
||||
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Shlinkio\Shlink\Core\Service\ShortUrl;
|
||||
|
||||
use Shlinkio\Shlink\Core\Exception;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
|
||||
interface DeleteShortUrlServiceInterface
|
||||
{
|
||||
@ -12,5 +13,5 @@ interface DeleteShortUrlServiceInterface
|
||||
* @throws Exception\ShortUrlNotFoundException
|
||||
* @throws Exception\DeleteShortUrlException
|
||||
*/
|
||||
public function deleteByShortCode(string $shortCode, bool $ignoreThreshold = false): void;
|
||||
public function deleteByShortCode(ShortUrlIdentifier $identifier, bool $ignoreThreshold = false): void;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\Exception\DeleteShortUrlException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\Visitor;
|
||||
use Shlinkio\Shlink\Core\Options\DeleteShortUrlsOptions;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
||||
@ -51,7 +52,7 @@ class DeleteShortUrlServiceTest extends TestCase
|
||||
$this->shortCode,
|
||||
));
|
||||
|
||||
$service->deleteByShortCode($this->shortCode);
|
||||
$service->deleteByShortCode(new ShortUrlIdentifier($this->shortCode));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@ -62,7 +63,7 @@ class DeleteShortUrlServiceTest extends TestCase
|
||||
$remove = $this->em->remove(Argument::type(ShortUrl::class))->willReturn(null);
|
||||
$flush = $this->em->flush()->willReturn(null);
|
||||
|
||||
$service->deleteByShortCode($this->shortCode, true);
|
||||
$service->deleteByShortCode(new ShortUrlIdentifier($this->shortCode), true);
|
||||
|
||||
$remove->shouldHaveBeenCalledOnce();
|
||||
$flush->shouldHaveBeenCalledOnce();
|
||||
@ -76,7 +77,7 @@ class DeleteShortUrlServiceTest extends TestCase
|
||||
$remove = $this->em->remove(Argument::type(ShortUrl::class))->willReturn(null);
|
||||
$flush = $this->em->flush()->willReturn(null);
|
||||
|
||||
$service->deleteByShortCode($this->shortCode);
|
||||
$service->deleteByShortCode(new ShortUrlIdentifier($this->shortCode));
|
||||
|
||||
$remove->shouldHaveBeenCalledOnce();
|
||||
$flush->shouldHaveBeenCalledOnce();
|
||||
@ -90,7 +91,7 @@ class DeleteShortUrlServiceTest extends TestCase
|
||||
$remove = $this->em->remove(Argument::type(ShortUrl::class))->willReturn(null);
|
||||
$flush = $this->em->flush()->willReturn(null);
|
||||
|
||||
$service->deleteByShortCode($this->shortCode);
|
||||
$service->deleteByShortCode(new ShortUrlIdentifier($this->shortCode));
|
||||
|
||||
$remove->shouldHaveBeenCalledOnce();
|
||||
$flush->shouldHaveBeenCalledOnce();
|
||||
|
@ -8,6 +8,7 @@ use Laminas\Diactoros\Response\EmptyResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\DeleteShortUrlServiceInterface;
|
||||
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
||||
|
||||
@ -26,8 +27,8 @@ class DeleteShortUrlAction extends AbstractRestAction
|
||||
|
||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$shortCode = $request->getAttribute('shortCode', '');
|
||||
$this->deleteShortUrlService->deleteByShortCode($shortCode);
|
||||
$identifier = ShortUrlIdentifier::fromApiRequest($request);
|
||||
$this->deleteShortUrlService->deleteByShortCode($identifier);
|
||||
return new EmptyResponse();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user