Passed
Pull Request — master (#588)
by Alejandro
03:34
created

ListShortUrlsCommandTest::provideArgs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 21
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 32
rs 9.584
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\CLI\Command\ShortUrl;
6
7
use Cake\Chronos\Chronos;
8
use PHPUnit\Framework\TestCase;
9
use Prophecy\Argument;
10
use Prophecy\Prophecy\ObjectProphecy;
11
use Shlinkio\Shlink\CLI\Command\ShortUrl\ListShortUrlsCommand;
12
use Shlinkio\Shlink\Common\Util\DateRange;
13
use Shlinkio\Shlink\Core\Entity\ShortUrl;
14
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
15
use Symfony\Component\Console\Application;
16
use Symfony\Component\Console\Tester\CommandTester;
17
use Zend\Paginator\Adapter\ArrayAdapter;
18
use Zend\Paginator\Paginator;
19
20
use function explode;
21
22
class ListShortUrlsCommandTest extends TestCase
23
{
24
    /** @var CommandTester */
25
    private $commandTester;
26
    /** @var ObjectProphecy */
27
    private $shortUrlService;
28
29
    public function setUp(): void
30
    {
31
        $this->shortUrlService = $this->prophesize(ShortUrlServiceInterface::class);
32
        $app = new Application();
33
        $command = new ListShortUrlsCommand($this->shortUrlService->reveal(), []);
34
        $app->add($command);
35
        $this->commandTester = new CommandTester($command);
36
    }
37
38
    /** @test */
39
    public function loadingMorePagesCallsListMoreTimes(): void
40
    {
41
        // The paginator will return more than one page
42
        $data = [];
43
        for ($i = 0; $i < 50; $i++) {
44
            $data[] = new ShortUrl('url_' . $i);
45
        }
46
47
        $this->shortUrlService->listShortUrls(Argument::cetera())->will(function () use (&$data) {
48
            return new Paginator(new ArrayAdapter($data));
49
        })->shouldBeCalledTimes(3);
50
51
        $this->commandTester->setInputs(['y', 'y', 'n']);
52
        $this->commandTester->execute([]);
53
        $output = $this->commandTester->getDisplay();
54
55
        $this->assertStringContainsString('Continue with page 2?', $output);
56
        $this->assertStringContainsString('Continue with page 3?', $output);
57
        $this->assertStringContainsString('Continue with page 4?', $output);
58
    }
59
60
    /** @test */
61
    public function havingMorePagesButAnsweringNoCallsListJustOnce(): void
62
    {
63
        // The paginator will return more than one page
64
        $data = [];
65
        for ($i = 0; $i < 30; $i++) {
66
            $data[] = new ShortUrl('url_' . $i);
67
        }
68
69
        $this->shortUrlService->listShortUrls(1, null, [], null, new DateRange())
70
            ->willReturn(new Paginator(new ArrayAdapter($data)))
71
            ->shouldBeCalledOnce();
72
73
        $this->commandTester->setInputs(['n']);
74
        $this->commandTester->execute([]);
75
        $output = $this->commandTester->getDisplay();
76
77
        $this->assertStringContainsString('url_1', $output);
78
        $this->assertStringContainsString('url_9', $output);
79
        $this->assertStringNotContainsString('url_10', $output);
80
        $this->assertStringNotContainsString('url_20', $output);
81
        $this->assertStringNotContainsString('url_30', $output);
82
        $this->assertStringContainsString('Continue with page 2?', $output);
83
        $this->assertStringNotContainsString('Continue with page 3?', $output);
84
    }
85
86
    /** @test */
87
    public function passingPageWillMakeListStartOnThatPage(): void
88
    {
89
        $page = 5;
90
        $this->shortUrlService->listShortUrls($page, null, [], null, new DateRange())
91
            ->willReturn(new Paginator(new ArrayAdapter()))
92
            ->shouldBeCalledOnce();
93
94
        $this->commandTester->setInputs(['y']);
95
        $this->commandTester->execute(['--page' => $page]);
96
    }
97
98
    /** @test */
99
    public function ifTagsFlagIsProvidedTagsColumnIsIncluded(): void
100
    {
101
        $this->shortUrlService->listShortUrls(1, null, [], null, new DateRange())
102
            ->willReturn(new Paginator(new ArrayAdapter()))
103
            ->shouldBeCalledOnce();
104
105
        $this->commandTester->setInputs(['y']);
106
        $this->commandTester->execute(['--showTags' => true]);
107
        $output = $this->commandTester->getDisplay();
108
        $this->assertStringContainsString('Tags', $output);
109
    }
110
111
    /**
112
     * @test
113
     * @dataProvider provideArgs
114
     */
115
    public function serviceIsInvokedWithProvidedArgs(
116
        array $commandArgs,
117
        ?int $page,
118
        ?string $searchTerm,
119
        array $tags,
120
        ?DateRange $dateRange
121
    ): void {
122
        $listShortUrls = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, null, $dateRange)
123
            ->willReturn(new Paginator(new ArrayAdapter()));
124
125
        $this->commandTester->setInputs(['n']);
126
        $this->commandTester->execute($commandArgs);
127
128
        $listShortUrls->shouldHaveBeenCalledOnce();
129
    }
130
131
    public function provideArgs(): iterable
132
    {
133
        yield [[], 1, null, [], new DateRange()];
134
        yield [['--page' => $page = 3], $page, null, [], new DateRange()];
135
        yield [['--searchTerm' => $searchTerm = 'search this'], 1, $searchTerm, [], new DateRange()];
136
        yield [
137
            ['--page' => $page = 3, '--searchTerm' => $searchTerm = 'search this', '--tags' => $tags = 'foo,bar'],
138
            $page,
139
            $searchTerm,
140
            explode(',', $tags),
141
            new DateRange(),
142
        ];
143
        yield [
144
            ['--startDate' => $startDate = '2019-01-01'],
145
            1,
146
            null,
147
            [],
148
            new DateRange(Chronos::parse($startDate)),
149
        ];
150
        yield [
151
            ['--endDate' => $endDate = '2020-05-23'],
152
            1,
153
            null,
154
            [],
155
            new DateRange(null, Chronos::parse($endDate)),
156
        ];
157
        yield [
158
            ['--startDate' => $startDate = '2019-01-01', '--endDate' => $endDate = '2020-05-23'],
159
            1,
160
            null,
161
            [],
162
            new DateRange(Chronos::parse($startDate), Chronos::parse($endDate)),
163
        ];
164
    }
165
166
    /**
167
     * @test
168
     * @dataProvider provideOrderBy
169
     */
170
    public function orderByIsProperlyComputed(array $commandArgs, $expectedOrderBy): void
171
    {
172
        $listShortUrls = $this->shortUrlService->listShortUrls(1, null, [], $expectedOrderBy, new DateRange())
173
            ->willReturn(new Paginator(new ArrayAdapter()));
174
175
        $this->commandTester->setInputs(['n']);
176
        $this->commandTester->execute($commandArgs);
177
178
        $listShortUrls->shouldHaveBeenCalledOnce();
179
    }
180
181
    public function provideOrderBy(): iterable
182
    {
183
        yield [[], null];
184
        yield [['--orderBy' => 'foo'], 'foo'];
185
        yield [['--orderBy' => 'foo,ASC'], ['foo' => 'ASC']];
186
        yield [['--orderBy' => 'bar,DESC'], ['bar' => 'DESC']];
187
    }
188
}
189