Passed
Pull Request — master (#354)
by Alejandro
05:24
created

deleteIsRetriedWhenThresholdIsReachedAndQuestionIsAccepted()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 26
rs 9.7666
c 0
b 0
f 0
cc 2
nc 1
nop 3
1
<?php
2
declare(strict_types=1);
3
4
namespace ShlinkioTest\Shlink\CLI\Command\ShortUrl;
5
6
use PHPUnit\Framework\TestCase;
7
use Prophecy\Argument;
8
use Prophecy\Prophecy\ObjectProphecy;
9
use Shlinkio\Shlink\CLI\Command\ShortUrl\DeleteShortUrlCommand;
10
use Shlinkio\Shlink\Core\Exception;
11
use Shlinkio\Shlink\Core\Service\ShortUrl\DeleteShortUrlServiceInterface;
12
use Symfony\Component\Console\Application;
13
use Symfony\Component\Console\Tester\CommandTester;
14
use const PHP_EOL;
15
use function array_pop;
16
use function sprintf;
17
18
class DeleteShortUrlCommandTest extends TestCase
19
{
20
    /** @var CommandTester */
21
    private $commandTester;
22
    /** @var ObjectProphecy */
23
    private $service;
24
25
    public function setUp(): void
26
    {
27
        $this->service = $this->prophesize(DeleteShortUrlServiceInterface::class);
28
29
        $command = new DeleteShortUrlCommand($this->service->reveal());
30
        $app = new Application();
31
        $app->add($command);
32
33
        $this->commandTester = new CommandTester($command);
34
    }
35
36
    /** @test */
37
    public function successMessageIsPrintedIfUrlIsProperlyDeleted(): void
38
    {
39
        $shortCode = 'abc123';
40
        $deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->will(function () {
41
        });
42
43
        $this->commandTester->execute(['shortCode' => $shortCode]);
44
        $output = $this->commandTester->getDisplay();
45
46
        $this->assertStringContainsString(
47
            sprintf('Short URL with short code "%s" successfully deleted.', $shortCode),
48
            $output
49
        );
50
        $deleteByShortCode->shouldHaveBeenCalledOnce();
51
    }
52
53
    /** @test */
54
    public function invalidShortCodePrintsMessage(): void
55
    {
56
        $shortCode = 'abc123';
57
        $deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow(
58
            Exception\InvalidShortCodeException::class
59
        );
60
61
        $this->commandTester->execute(['shortCode' => $shortCode]);
62
        $output = $this->commandTester->getDisplay();
63
64
        $this->assertStringContainsString(sprintf('Provided short code "%s" could not be found.', $shortCode), $output);
65
        $deleteByShortCode->shouldHaveBeenCalledOnce();
66
    }
67
68
    /**
69
     * @test
70
     * @dataProvider provideRetryDeleteAnswers
71
     */
72
    public function deleteIsRetriedWhenThresholdIsReachedAndQuestionIsAccepted(
73
        array $retryAnswer,
74
        int $expectedDeleteCalls,
75
        string $expectedMessage
76
    ): void {
77
        $shortCode = 'abc123';
78
        $deleteByShortCode = $this->service->deleteByShortCode($shortCode, Argument::type('bool'))->will(
79
            function (array $args) {
80
                $ignoreThreshold = array_pop($args);
81
82
                if (!$ignoreThreshold) {
83
                    throw new Exception\DeleteShortUrlException(10);
84
                }
85
            }
86
        );
87
        $this->commandTester->setInputs($retryAnswer);
88
89
        $this->commandTester->execute(['shortCode' => $shortCode]);
90
        $output = $this->commandTester->getDisplay();
91
92
        $this->assertStringContainsString(sprintf(
93
            'It was not possible to delete the short URL with short code "%s" because it has more than 10 visits.',
94
            $shortCode
95
        ), $output);
96
        $this->assertStringContainsString($expectedMessage, $output);
97
        $deleteByShortCode->shouldHaveBeenCalledTimes($expectedDeleteCalls);
98
    }
99
100
    public function provideRetryDeleteAnswers(): iterable
101
    {
102
        yield 'answering yes to retry' => [['yes'], 2, 'Short URL with short code "abc123" successfully deleted.'];
103
        yield 'answering no to retry' => [['no'], 1, 'Short URL was not deleted.'];
104
        yield 'answering default to retry' => [[PHP_EOL], 1, 'Short URL was not deleted.'];
105
    }
106
107
    /** @test */
108
    public function deleteIsNotRetriedWhenThresholdIsReachedAndQuestionIsDeclined(): void
109
    {
110
        $shortCode = 'abc123';
111
        $deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow(
112
            new Exception\DeleteShortUrlException(10)
113
        );
114
        $this->commandTester->setInputs(['no']);
115
116
        $this->commandTester->execute(['shortCode' => $shortCode]);
117
        $output = $this->commandTester->getDisplay();
118
119
        $this->assertStringContainsString(sprintf(
120
            'It was not possible to delete the short URL with short code "%s" because it has more than 10 visits.',
121
            $shortCode
122
        ), $output);
123
        $this->assertStringContainsString('Short URL was not deleted.', $output);
124
        $deleteByShortCode->shouldHaveBeenCalledOnce();
125
    }
126
}
127